Fixed several disconnect event issues

This commit is contained in:
RaphiMC 2023-11-30 21:38:54 +01:00
parent ad75c26459
commit e4881bd99d
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
11 changed files with 84 additions and 93 deletions

View File

@ -33,11 +33,11 @@ import net.raphimc.vialoader.util.VersionEnum;
import org.apache.commons.lang3.tuple.Pair;
public class ClientPlayerInteractionManager1_18_2 {
private static final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, Pair<Vec3d, Vec2f>> UN_ACKED_ACTIONS = new Object2ObjectLinkedOpenHashMap<>();
public static void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, Pair<Vec3d, Vec2f>> unAckedActions = new Object2ObjectLinkedOpenHashMap<>();
public void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
final var player = MinecraftClient.getInstance().player;
if (player == null) return;
final Vec2f rotation;
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) {
@ -45,15 +45,15 @@ public class ClientPlayerInteractionManager1_18_2 {
} else {
rotation = new Vec2f(player.getYaw(), player.getPitch());
}
UN_ACKED_ACTIONS.put(Pair.of(blockPos, action), Pair.of(player.getPos(), rotation));
unAckedActions.put(Pair.of(blockPos, action), Pair.of(player.getPos(), rotation));
}
public static void handleBlockBreakAck(final BlockPos blockPos, final BlockState expectedState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
public void handleBlockBreakAck(final BlockPos blockPos, final BlockState expectedState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
final var player = MinecraftClient.getInstance().player;
if (player == null) return;
final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld();
final var oldPlayerState = UN_ACKED_ACTIONS.remove(Pair.of(blockPos, action));
final var oldPlayerState = unAckedActions.remove(Pair.of(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))) {
@ -68,14 +68,10 @@ public class ClientPlayerInteractionManager1_18_2 {
}
}
while (UN_ACKED_ACTIONS.size() >= 50) {
ViaFabricPlus.global().getLogger().warn("Too many unacked block actions, dropping {}", UN_ACKED_ACTIONS.firstKey());
UN_ACKED_ACTIONS.removeFirst();
while (unAckedActions.size() >= 50) {
ViaFabricPlus.global().getLogger().warn("Too many unacked block actions, dropping {}", unAckedActions.firstKey());
unAckedActions.removeFirst();
}
}
public static void clearUnackedActions() {
UN_ACKED_ACTIONS.clear();
}
}

View File

@ -20,15 +20,13 @@
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.data.ResourcePackHeaderDiff;
import de.florianmichael.viafabricplus.fixes.entity.EntityDimensionReplacements;
import de.florianmichael.viafabricplus.fixes.classic.CPEAdditions;
import de.florianmichael.viafabricplus.fixes.classic.GridItemSelectionScreen;
import de.florianmichael.viafabricplus.fixes.data.ResourcePackHeaderDiff;
import de.florianmichael.viafabricplus.fixes.entity.EntityDimensionReplacements;
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.FontStorage;
@ -77,17 +75,6 @@ public class ClientsideFixes {
ArmorHudEmulation1_8.init();
});
DisconnectCallback.EVENT.register(() -> {
// Reset the MP-pass
ViaFabricPlusClassicMPPassProvider.classiCubeMPPass = null;
// Remove all previous unacked player actions
ClientPlayerInteractionManager1_18_2.clearUnackedActions();
// Rebuilt the item selection screen grid next time the screen is opened
GridItemSelectionScreen.INSTANCE.itemGrid = null;
});
// Reloads some clientside stuff when the protocol version changes
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> {
// Calculates the current chat length limit

View File

@ -17,21 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.event;
package de.florianmichael.viafabricplus.injection.access;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import de.florianmichael.viafabricplus.fixes.ClientPlayerInteractionManager1_18_2;
/**
* This event is fired when the user disconnects from a server.
*/
public interface DisconnectCallback {
public interface IClientPlayerInteractionManager {
Event<DisconnectCallback> EVENT = EventFactory.createArrayBacked(DisconnectCallback.class, listeners -> () -> {
for (DisconnectCallback listener : listeners) {
listener.onDisconnect();
}
});
ClientPlayerInteractionManager1_18_2 viaFabricPlus$get1_18_2InteractionManager();
void onDisconnect();
}

View File

@ -21,7 +21,6 @@ package de.florianmichael.viafabricplus.injection.mixin.base.connect;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.event.DisconnectCallback;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
@ -37,7 +36,6 @@ import net.minecraft.network.ClientConnection;
import net.minecraft.network.encryption.PacketDecryptor;
import net.minecraft.network.encryption.PacketEncryptor;
import net.minecraft.network.packet.Packet;
import net.minecraft.text.Text;
import net.minecraft.util.profiler.PerformanceLog;
import net.raphimc.vialoader.netty.CompressionReorderEvent;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
@ -171,11 +169,6 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
return instance.connect(inetHost, inetPort);
}
@Inject(method = "disconnect", at = @At("RETURN"))
private void callDisconnectCallback(Text disconnectReason, CallbackInfo ci) {
DisconnectCallback.EVENT.invoker().onDisconnect();
}
@Unique
public void viaFabricPlus$setupPreNettyEncryption(final Cipher encryptionCipher) {
if (encryptionCipher == null) {

View File

@ -19,6 +19,8 @@
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
@ -26,19 +28,19 @@ import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabric
import de.florianmichael.viafabricplus.protocolhack.util.ProtocolVersionDetector;
import de.florianmichael.viafabricplus.protocolhack.util.VersionEnumExtension;
import de.florianmichael.viafabricplus.settings.impl.AuthenticationSettings;
import io.netty.channel.ChannelFuture;
import net.minecraft.client.gui.screen.ConnectScreen;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.session.Session;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.Text;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.net.InetSocketAddress;
@ -53,9 +55,34 @@ public abstract class MixinConnectScreen_1 {
@Final
ConnectScreen field_2416;
@Unique
private boolean viaFabricPlus$useClassiCubeAccount;
@WrapOperation(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;"))
private ChannelFuture setServerInfoAndHandleDisconnect(InetSocketAddress address, boolean useEpoll, ClientConnection connection, Operation<ChannelFuture> original) {
final IServerInfo mixinServerInfo = (IServerInfo) this.field_40415;
VersionEnum targetVersion = ProtocolHack.getTargetVersion();
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
targetVersion = mixinServerInfo.viaFabricPlus$forcedVersion();
}
if (targetVersion == VersionEnumExtension.AUTO_DETECT) {
this.field_2416.setStatus(Text.translatable("base.viafabricplus.detecting_server_version"));
targetVersion = ProtocolVersionDetector.get(address, ProtocolHack.NATIVE_VERSION);
}
ProtocolHack.setTargetVersion(targetVersion, true);
this.viaFabricPlus$useClassiCubeAccount = AuthenticationSettings.global().setSessionNameToClassiCubeNameInServerList.getValue() && ViaFabricPlusClassicMPPassProvider.classicMpPassForNextJoin != null;
final ChannelFuture future = original.call(address, useEpoll, connection);
future.channel().closeFuture().addListener(channel -> ProtocolHack.resetPreviousVersion());
return future;
}
@Redirect(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/session/Session;getUsername()Ljava/lang/String;"))
private String useClassiCubeUsername(Session instance) {
if (AuthenticationSettings.global().setSessionNameToClassiCubeNameInServerList.getValue() && ViaFabricPlusClassicMPPassProvider.classiCubeMPPass != null) {
if (this.viaFabricPlus$useClassiCubeAccount) {
final var account = ViaFabricPlus.global().getSaveManager().getAccountsSave().getClassicubeAccount();
if (account != null) {
return account.username();
@ -65,22 +92,4 @@ public abstract class MixinConnectScreen_1 {
return instance.getUsername();
}
@SuppressWarnings("InvalidInjectorMethodSignature")
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
private void setServerInfo(CallbackInfo ci, InetSocketAddress inetSocketAddress) {
final IServerInfo mixinServerInfo = (IServerInfo) this.field_40415;
VersionEnum targetVersion = ProtocolHack.getTargetVersion();
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
targetVersion = mixinServerInfo.viaFabricPlus$forcedVersion();
}
if (targetVersion == VersionEnumExtension.AUTO_DETECT) {
this.field_2416.setStatus(Text.translatable("base.viafabricplus.detecting_server_version"));
targetVersion = ProtocolVersionDetector.get(inetSocketAddress, ProtocolHack.NATIVE_VERSION);
}
ProtocolHack.setTargetVersion(targetVersion, true);
}
}

View File

@ -28,6 +28,7 @@ import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_
import de.florianmichael.viafabricplus.fixes.ActionResultException1_12_2;
import de.florianmichael.viafabricplus.fixes.ClientPlayerInteractionManager1_18_2;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.injection.access.IClientPlayerInteractionManager;
import de.florianmichael.viafabricplus.injection.access.IScreenHandler;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.ViaFabricPlusHandItemProvider;
@ -72,7 +73,7 @@ import java.util.List;
@SuppressWarnings("DataFlowIssue")
@Mixin(ClientPlayerInteractionManager.class)
public abstract class MixinClientPlayerInteractionManager {
public abstract class MixinClientPlayerInteractionManager implements IClientPlayerInteractionManager {
@Shadow
@Final
@ -103,6 +104,9 @@ public abstract class MixinClientPlayerInteractionManager {
@Unique
private List<ItemStack> viaFabricPlus$oldItems;
@Unique
private final ClientPlayerInteractionManager1_18_2 viaFabricPlus$1_18_2InteractionManager = new ClientPlayerInteractionManager1_18_2();
@Inject(method = "getBlockBreakingProgress", at = @At("HEAD"), cancellable = true)
private void changeCalculation(CallbackInfoReturnable<Integer> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
@ -113,14 +117,14 @@ public abstract class MixinClientPlayerInteractionManager {
@Inject(method = "sendSequencedPacket", at = @At("HEAD"))
private void trackPlayerAction(ClientWorld world, SequencedPacketCreator packetCreator, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_14_4, VersionEnum.r1_18_2) && packetCreator instanceof PlayerActionC2SPacket playerActionC2SPacket) {
ClientPlayerInteractionManager1_18_2.trackPlayerAction(playerActionC2SPacket.getAction(), playerActionC2SPacket.getPos());
this.viaFabricPlus$1_18_2InteractionManager.trackPlayerAction(playerActionC2SPacket.getAction(), playerActionC2SPacket.getPos());
}
}
@Redirect(method = {"attackBlock", "cancelBlockBreaking"}, at = @At(value = "NEW", target = "(Lnet/minecraft/network/packet/c2s/play/PlayerActionC2SPacket$Action;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/network/packet/c2s/play/PlayerActionC2SPacket;"))
private PlayerActionC2SPacket trackPlayerAction(PlayerActionC2SPacket.Action action, BlockPos pos, Direction direction) {
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_14_4, VersionEnum.r1_18_2)) {
ClientPlayerInteractionManager1_18_2.trackPlayerAction(action, pos);
this.viaFabricPlus$1_18_2InteractionManager.trackPlayerAction(action, pos);
}
return new PlayerActionC2SPacket(action, pos, direction);
}
@ -321,4 +325,9 @@ public abstract class MixinClientPlayerInteractionManager {
return type == SlotActionType.PICKUP && slot == -999;
}
@Override
public ClientPlayerInteractionManager1_18_2 viaFabricPlus$get1_18_2InteractionManager() {
return this.viaFabricPlus$1_18_2InteractionManager;
}
}

View File

@ -25,9 +25,10 @@ import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPacke
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.fixes.ClientPlayerInteractionManager1_18_2;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IClientPlayerInteractionManager;
import de.florianmichael.viafabricplus.protocolhack.translator.BlockStateTranslator;
import net.minecraft.client.MinecraftClient;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -48,7 +49,8 @@ public abstract class MixinWorldPackets1_19 {
final var action = data.readEnumConstant(PlayerActionC2SPacket.Action.class);
final var allGood = data.readBoolean();
ClientPlayerInteractionManager1_18_2.handleBlockBreakAck(pos, blockState, action, allGood);
final IClientPlayerInteractionManager interactionManager = (IClientPlayerInteractionManager) MinecraftClient.getInstance().interactionManager;
interactionManager.viaFabricPlus$get1_18_2InteractionManager().handleBlockBreakAck(pos, blockState, action, allGood);
} catch (Throwable t) {
throw new RuntimeException("Failed to handle BlockBreakAck packet data", t);
}

View File

@ -31,7 +31,6 @@ import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.event.DisconnectCallback;
import de.florianmichael.viafabricplus.event.PostViaVersionLoadCallback;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocolhack.command.ViaFabricPlusVLCommandHandler;
@ -159,6 +158,16 @@ public class ProtocolHack {
}
}
/**
* Resets the previous version if it is set. Calling {@link #setTargetVersion(VersionEnum, boolean)} with revertOnDisconnect set to true will set it.
*/
public static void resetPreviousVersion() {
if (previousVersion != null) { // Revert the version if the player disconnects and a previous version is set
setTargetVersion(previousVersion);
previousVersion = null;
}
}
/**
* @param clientVersion The client version
* @param serverVersion The server version
@ -228,13 +237,6 @@ public class ProtocolHack {
* @return A CompletableFuture that will be completed when the initialization is done
*/
public static CompletableFuture<Void> init(final File directory) {
DisconnectCallback.EVENT.register(() -> {
if (previousVersion != null) { // Revert the version if the player disconnects and a previous version is set
setTargetVersion(previousVersion);
previousVersion = null;
}
});
patchConfigs(directory);
// Register command callback for /viaversion and /viafabricplus

View File

@ -29,12 +29,15 @@ import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.provide
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.HandshakeStorage;
public class ViaFabricPlusClassicMPPassProvider extends ClassicMPPassProvider {
public static String classiCubeMPPass;
public static String classicMpPassForNextJoin;
@Override
public String getMpPass(UserConnection user) {
if (classiCubeMPPass != null) {
return classiCubeMPPass;
if (classicMpPassForNextJoin != null) {
final String mpPass = classicMpPassForNextJoin;
classicMpPassForNextJoin = null;
return mpPass;
}
if (AuthenticationSettings.global().useBetaCraftAuthentication.getValue()) {
@ -56,4 +59,5 @@ public class ViaFabricPlusClassicMPPassProvider extends ClassicMPPassProvider {
return super.getMpPass(user);
}
}
}

View File

@ -26,9 +26,9 @@ import de.florianmichael.classic4j.model.classicube.server.CCServerInfo;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
import de.florianmichael.viafabricplus.screen.MainScreen;
import de.florianmichael.viafabricplus.screen.base.VFPListEntry;
import de.florianmichael.viafabricplus.screen.base.VFPScreen;
import de.florianmichael.viafabricplus.screen.MainScreen;
import de.florianmichael.viafabricplus.settings.impl.AuthenticationSettings;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
@ -137,7 +137,7 @@ public class ClassiCubeServerListScreen extends VFPScreen {
public void mappedMouseClicked(double mouseX, double mouseY, int button) {
final ServerAddress serverAddress = ServerAddress.parse(classiCubeServerInfo.ip() + ":" + classiCubeServerInfo.port());
final ServerInfo entry = new ServerInfo(classiCubeServerInfo.name(), serverAddress.getAddress(), ServerInfo.ServerType.OTHER);
ViaFabricPlusClassicMPPassProvider.classiCubeMPPass = classiCubeServerInfo.mpPass();
ViaFabricPlusClassicMPPassProvider.classicMpPassForNextJoin = classiCubeServerInfo.mpPass();
if (AuthenticationSettings.global().automaticallySelectCPEInClassiCubeServerList.getValue()) {
((IServerInfo) entry).viaFabricPlus$forceVersion(VersionEnum.c0_30cpe);

View File

@ -193,15 +193,13 @@
"viabedrock.MixinBlobCache",
"viabedrock.MixinJoinPackets",
"vialegacy.MixinExtensionProtocolMetadataStorage",
"vialegacy.MixinViaLegacyConfig",
"viaversion.MixinAbstractFenceConnectionHandler",
"viaversion.MixinConfig",
"viaversion.MixinGlassConnectionHandler",
"viaversion.MixinProtocolVersion"
],
"injectors": {
"defaultRequire": 1
},
"mixins": [
"vialegacy.MixinViaLegacyConfig",
"viaversion.MixinConfig"
]
}
}