Apply changes on other class files

This commit is contained in:
FlorianMichael 2024-01-23 21:04:53 +01:00
parent cb31189cb8
commit 55eb34b5a5
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
39 changed files with 109 additions and 90 deletions

View File

@ -148,13 +148,13 @@ public class ClientsideFixes {
* @return The uuid of the task * @return The uuid of the task
*/ */
public static String executeSyncTask(final Consumer<PacketByteBuf> task) { public static String executeSyncTask(final Consumer<PacketByteBuf> task) {
final var uuid = UUID.randomUUID().toString(); final String uuid = UUID.randomUUID().toString();
PENDING_EXECUTION_TASKS.put(uuid, task); PENDING_EXECUTION_TASKS.put(uuid, task);
return uuid; return uuid;
} }
public static void handleSyncTask(final PacketByteBuf buf) { public static void handleSyncTask(final PacketByteBuf buf) {
final var uuid = buf.readString(); final String uuid = buf.readString();
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) { if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread

View File

@ -45,7 +45,6 @@ public class WolfHealthTracker extends StoredObject {
if (tracker == null) { if (tracker == null) {
userConnection.put(tracker = new WolfHealthTracker(userConnection)); userConnection.put(tracker = new WolfHealthTracker(userConnection));
} }
return tracker; return tracker;
} }

View File

@ -25,6 +25,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec2f;
@ -37,7 +38,7 @@ public class ClientPlayerInteractionManager1_18_2 {
private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, Pair<Vec3d, Vec2f>> unAckedActions = new Object2ObjectLinkedOpenHashMap<>(); private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, Pair<Vec3d, Vec2f>> unAckedActions = new Object2ObjectLinkedOpenHashMap<>();
public void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) { public void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
final var player = MinecraftClient.getInstance().player; final ClientPlayerEntity player = MinecraftClient.getInstance().player;
final Vec2f rotation; final Vec2f rotation;
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) { if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) {
@ -51,6 +52,7 @@ public class ClientPlayerInteractionManager1_18_2 {
public 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; final var player = MinecraftClient.getInstance().player;
if (player == null) return; if (player == null) return;
final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld(); final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld();
final var oldPlayerState = unAckedActions.remove(Pair.of(blockPos, action)); final var oldPlayerState = unAckedActions.remove(Pair.of(blockPos, action));

View File

@ -41,12 +41,11 @@ public class ListExtensionsCommand extends VFPViaSubCommand {
@Override @Override
public boolean execute(ViaCommandSender sender, String[] args) { public boolean execute(ViaCommandSender sender, String[] args) {
final UserConnection connection = getUser(); if (!getUser().has(ExtensionProtocolMetadataStorage.class)) {
if (!connection.has(ExtensionProtocolMetadataStorage.class)) {
sendMessage(sender, Formatting.RED + "Only for " + VersionEnum.c0_30cpe.getName()); sendMessage(sender, Formatting.RED + "Only for " + VersionEnum.c0_30cpe.getName());
return true; return true;
} }
((IExtensionProtocolMetadataStorage) connection.get(ExtensionProtocolMetadataStorage.class)).viaFabricPlus$getServerExtensions().forEach((extension, version) -> { ((IExtensionProtocolMetadataStorage) getUser().get(ExtensionProtocolMetadataStorage.class)).viaFabricPlus$getServerExtensions().forEach((extension, version) -> {
sendMessage(sender, Formatting.GREEN + extension.getName() + Formatting.GOLD + " v" + version); sendMessage(sender, Formatting.GREEN + extension.getName() + Formatting.GOLD + " v" + version);
}); });
return true; return true;

View File

@ -45,15 +45,14 @@ public class SetTimeCommand extends VFPViaSubCommand {
@Override @Override
public boolean execute(ViaCommandSender sender, String[] args) { public boolean execute(ViaCommandSender sender, String[] args) {
final UserConnection connection = getUser(); if (!getUser().has(TimeLockStorage.class)) {
if (!connection.has(TimeLockStorage.class)) {
sendMessage(sender, Formatting.RED + "Only for <= " + VersionEnum.a1_0_16toa1_0_16_2.getName()); sendMessage(sender, Formatting.RED + "Only for <= " + VersionEnum.a1_0_16toa1_0_16_2.getName());
return true; return true;
} }
try { try {
if (args.length == 1) { if (args.length == 1) {
final long time = Long.parseLong(args[0]) % 24_000L; final long time = Long.parseLong(args[0]) % 24_000L;
connection.get(TimeLockStorage.class).setTime(time); getUser().get(TimeLockStorage.class).setTime(time);
sendMessage(sender, Formatting.GREEN + "Time has been set to " + Formatting.GOLD + time); sendMessage(sender, Formatting.GREEN + "Time has been set to " + Formatting.GOLD + time);
} else { } else {
return false; return false;

View File

@ -23,6 +23,7 @@ import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.PlayerEntityRenderer; import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.raphimc.vialoader.util.VersionEnum; import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -37,16 +38,15 @@ public abstract class MixinPlayerEntityRenderer {
@Inject(method = "getPositionOffset(Lnet/minecraft/client/network/AbstractClientPlayerEntity;F)Lnet/minecraft/util/math/Vec3d;", at = @At("RETURN"), cancellable = true) @Inject(method = "getPositionOffset(Lnet/minecraft/client/network/AbstractClientPlayerEntity;F)Lnet/minecraft/util/math/Vec3d;", at = @At("RETURN"), cancellable = true)
private void modifySleepingOffset(AbstractClientPlayerEntity player, float delta, CallbackInfoReturnable<Vec3d> cir) { private void modifySleepingOffset(AbstractClientPlayerEntity player, float delta, CallbackInfoReturnable<Vec3d> cir) {
if (player.getPose() == EntityPose.SLEEPING) { if (player.getPose() == EntityPose.SLEEPING) {
final var targetVersion = ProtocolHack.getTargetVersion(); final Direction sleepingDir = player.getSleepingDirection();
final var sleepingDir = player.getSleepingDirection();
if (sleepingDir != null) { if (sleepingDir != null) {
if (targetVersion.isOlderThanOrEqualTo(VersionEnum.r1_13_2)) { if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.4, 0, sleepingDir.getOffsetZ() * 0.4)); cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.4, 0, sleepingDir.getOffsetZ() * 0.4));
} }
if (targetVersion.isOlderThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) { if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.1, 0, sleepingDir.getOffsetZ() * 0.1)); cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.1, 0, sleepingDir.getOffsetZ() * 0.1));
} }
if (targetVersion.isBetweenInclusive(VersionEnum.b1_6tob1_6_6, VersionEnum.r1_7_6tor1_7_10)) { if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.b1_6tob1_6_6, VersionEnum.r1_7_6tor1_7_10)) {
cir.setReturnValue(cir.getReturnValue().subtract(0, 0.3F, 0)); cir.setReturnValue(cir.getReturnValue().subtract(0, 0.3F, 0));
} }
} }

View File

@ -31,6 +31,9 @@ import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ServerAddress; import net.minecraft.client.network.ServerAddress;
import net.minecraft.network.ClientConnection; import net.minecraft.network.ClientConnection;
import net.minecraft.network.encryption.PlayerKeyPair;
import net.minecraft.network.encryption.PlayerPublicKey;
import net.raphimc.minecraftauth.step.bedrock.StepMCChain;
import net.raphimc.viabedrock.protocol.storage.AuthChainData; import net.raphimc.viabedrock.protocol.storage.AuthChainData;
import net.raphimc.vialoader.util.VersionEnum; import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@ -42,6 +45,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.security.PrivateKey;
import java.util.UUID;
@Mixin(targets = "net.minecraft.client.gui.screen.multiplayer.ConnectScreen$1") @Mixin(targets = "net.minecraft.client.gui.screen.multiplayer.ConnectScreen$1")
public abstract class MixinConnectScreen_1 { public abstract class MixinConnectScreen_1 {
@ -77,13 +82,13 @@ public abstract class MixinConnectScreen_1 {
final UserConnection userConnection = ((IClientConnection) clientConnection).viaFabricPlus$getUserConnection(); final UserConnection userConnection = ((IClientConnection) clientConnection).viaFabricPlus$getUserConnection();
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_19, VersionEnum.r1_19_1tor1_19_2)) { if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_19, VersionEnum.r1_19_1tor1_19_2)) {
final var keyPair = MinecraftClient.getInstance().getProfileKeys().fetchKeyPair().join().orElse(null); final PlayerKeyPair keyPair = MinecraftClient.getInstance().getProfileKeys().fetchKeyPair().join().orElse(null);
if (keyPair != null) { if (keyPair != null) {
final var publicKeyData = keyPair.publicKey().data(); final PlayerPublicKey.PublicKeyData publicKeyData = keyPair.publicKey().data();
final var privateKey = keyPair.privateKey(); final PrivateKey privateKey = keyPair.privateKey();
final var expiresAt = publicKeyData.expiresAt().toEpochMilli(); final long expiresAt = publicKeyData.expiresAt().toEpochMilli();
final var publicKey = publicKeyData.key().getEncoded(); final byte[] publicKey = publicKeyData.key().getEncoded();
final var uuid = this.field_33738.getSession().getUuidOrNull(); final UUID uuid = this.field_33738.getSession().getUuidOrNull();
userConnection.put(new ChatSession1_19_1(uuid, privateKey, new ProfileKey(expiresAt, publicKey, publicKeyData.keySignature()))); userConnection.put(new ChatSession1_19_1(uuid, privateKey, new ProfileKey(expiresAt, publicKey, publicKeyData.keySignature())));
if (ProtocolHack.getTargetVersion() == VersionEnum.r1_19) { if (ProtocolHack.getTargetVersion() == VersionEnum.r1_19) {
@ -98,9 +103,9 @@ public abstract class MixinConnectScreen_1 {
} else if (ProtocolHack.getTargetVersion() == VersionEnum.bedrockLatest) { } else if (ProtocolHack.getTargetVersion() == VersionEnum.bedrockLatest) {
final var bedrockSession = ViaFabricPlus.global().getSaveManager().getAccountsSave().refreshAndGetBedrockAccount(); final var bedrockSession = ViaFabricPlus.global().getSaveManager().getAccountsSave().refreshAndGetBedrockAccount();
if (bedrockSession != null) { if (bedrockSession != null) {
final var mcChain = bedrockSession.getMcChain(); final StepMCChain.MCChain mcChain = bedrockSession.getMcChain();
final var deviceId = mcChain.getXblXsts().getInitialXblSession().getXblDeviceToken().getId(); final UUID deviceId = mcChain.getXblXsts().getInitialXblSession().getXblDeviceToken().getId();
final var playFabId = bedrockSession.getPlayFabToken().getPlayFabId(); final String playFabId = bedrockSession.getPlayFabToken().getPlayFabId();
userConnection.put(new AuthChainData(mcChain.getMojangJwt(), mcChain.getIdentityJwt(), mcChain.getPublicKey(), mcChain.getPrivateKey(), deviceId, playFabId)); userConnection.put(new AuthChainData(mcChain.getMojangJwt(), mcChain.getIdentityJwt(), mcChain.getPublicKey(), mcChain.getPrivateKey(), deviceId, playFabId));
} else { } else {

View File

@ -28,8 +28,10 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.WorldPac
import de.florianmichael.viafabricplus.fixes.ClientsideFixes; import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IClientPlayerInteractionManager; import de.florianmichael.viafabricplus.injection.access.IClientPlayerInteractionManager;
import de.florianmichael.viafabricplus.protocolhack.translator.BlockStateTranslator; import de.florianmichael.viafabricplus.protocolhack.translator.BlockStateTranslator;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
@ -42,12 +44,12 @@ public abstract class MixinWorldPackets1_19 {
instance.registerClientbound(ClientboundPackets1_18.ACKNOWLEDGE_PLAYER_DIGGING, ClientboundPackets1_19.PLUGIN_MESSAGE, wrapper -> { instance.registerClientbound(ClientboundPackets1_18.ACKNOWLEDGE_PLAYER_DIGGING, ClientboundPackets1_19.PLUGIN_MESSAGE, wrapper -> {
wrapper.resetReader(); wrapper.resetReader();
final var uuid = ClientsideFixes.executeSyncTask(data -> { final String uuid = ClientsideFixes.executeSyncTask(data -> {
try { try {
final var pos = data.readBlockPos(); final BlockPos pos = data.readBlockPos();
final var blockState = BlockStateTranslator.via1_18_2toMc(data.readVarInt()); final BlockState blockState = BlockStateTranslator.via1_18_2toMc(data.readVarInt());
final var action = data.readEnumConstant(PlayerActionC2SPacket.Action.class); final PlayerActionC2SPacket.Action action = data.readEnumConstant(PlayerActionC2SPacket.Action.class);
final var allGood = data.readBoolean(); final boolean allGood = data.readBoolean();
final var mixinInteractionManager = (IClientPlayerInteractionManager) MinecraftClient.getInstance().interactionManager; final var mixinInteractionManager = (IClientPlayerInteractionManager) MinecraftClient.getInstance().interactionManager;
mixinInteractionManager.viaFabricPlus$get1_18_2InteractionManager().handleBlockBreakAck(pos, blockState, action, allGood); mixinInteractionManager.viaFabricPlus$get1_18_2InteractionManager().handleBlockBreakAck(pos, blockState, action, allGood);

View File

@ -40,12 +40,11 @@ public class ViaFabricPlusTransferProvider extends TransferProvider {
final var mc = MinecraftClient.getInstance(); final var mc = MinecraftClient.getInstance();
mc.execute(() -> { mc.execute(() -> {
if (BedrockSettings.global().openPromptGUIToConfirmTransfer.getValue()) { if (BedrockSettings.global().openPromptGUIToConfirmTransfer.getValue()) {
mc.setScreen(new ConfirmScreen( mc.setScreen(new ConfirmScreen((bl) -> {
(bl) -> {
if (bl) { if (bl) {
connect(newAddress); connect(newAddress);
} else { } else {
MinecraftClient.getInstance().setScreen(null); mc.setScreen(null);
} }
}, },
Text.of("ViaFabricPlus"), Text.of("ViaFabricPlus"),

View File

@ -40,10 +40,10 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
} }
protected Item[] getMinecraftContainerItems(final List<ItemStack> trackingItems) { protected Item[] getMinecraftContainerItems(final List<ItemStack> trackingItems) {
final var items = new Item[trackingItems.size()]; final Item[] items = new Item[trackingItems.size()];
for (int i = 0; i < items.length; i++) { for (int i = 0; i < items.length; i++) {
final var alphaItem = trackingItems.get(i); final ItemStack alphaItem = trackingItems.get(i);
if (alphaItem.isEmpty()) continue; if (alphaItem.isEmpty()) continue;
items[i] = ItemTranslator.mcToVia(alphaItem, VersionEnum.b1_8tob1_8_1); items[i] = ItemTranslator.mcToVia(alphaItem, VersionEnum.b1_8tob1_8_1);
@ -55,36 +55,36 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
public Item[] getMainInventoryItems(UserConnection user) { public Item[] getMainInventoryItems(UserConnection user) {
if (getPlayer() == null) { if (getPlayer() == null) {
return new Item[37]; return new Item[37];
} else {
return getMinecraftContainerItems(getPlayer().getInventory().main);
} }
return getMinecraftContainerItems(getPlayer().getInventory().main);
} }
@Override @Override
public Item[] getCraftingInventoryItems(UserConnection user) { public Item[] getCraftingInventoryItems(UserConnection user) {
if (getPlayer() == null) { if (getPlayer() == null) {
return new Item[4]; return new Item[4];
} else {
return getMinecraftContainerItems(getPlayer().playerScreenHandler.getCraftingInput().getHeldStacks());
} }
return getMinecraftContainerItems(getPlayer().playerScreenHandler.getCraftingInput().getHeldStacks());
} }
@Override @Override
public Item[] getArmorInventoryItems(UserConnection user) { public Item[] getArmorInventoryItems(UserConnection user) {
if (getPlayer() == null) { if (getPlayer() == null) {
return new Item[4]; return new Item[4];
} else {
return getMinecraftContainerItems(getPlayer().getInventory().armor);
} }
return getMinecraftContainerItems(getPlayer().getInventory().armor);
} }
@Override @Override
public Item[] getContainerItems(UserConnection user) { public Item[] getContainerItems(UserConnection user) {
if (getPlayer() == null) { if (getPlayer() == null) {
return new Item[37]; return new Item[37];
} else {
return getMinecraftContainerItems(getPlayer().currentScreenHandler.getStacks());
} }
return getMinecraftContainerItems(getPlayer().currentScreenHandler.getStacks());
} }
@Override @Override

View File

@ -41,10 +41,8 @@ public class ViaFabricPlusClassicMPPassProvider extends ClassicMPPassProvider {
} }
if (AuthenticationSettings.global().useBetaCraftAuthentication.getValue()) { if (AuthenticationSettings.global().useBetaCraftAuthentication.getValue()) {
final var handshakeStorage = user.get(HandshakeStorage.class); final HandshakeStorage handshakeStorage = user.get(HandshakeStorage.class);
if (handshakeStorage == null) { if (handshakeStorage == null) return super.getMpPass(user);
return super.getMpPass(user);
}
return BetaCraftHandler.requestMPPass(user.getProtocolInfo().getUsername(), handshakeStorage.getHostname(), handshakeStorage.getPort(), serverId -> { return BetaCraftHandler.requestMPPass(user.getProtocolInfo().getUsername(), handshakeStorage.getHostname(), handshakeStorage.getPort(), serverId -> {
try { try {

View File

@ -25,6 +25,7 @@ import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException; import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import com.mojang.authlib.yggdrasil.ProfileResult;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.GameProfile; import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.GameProfile;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher; import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher;
@ -35,9 +36,9 @@ import java.util.concurrent.CompletableFuture;
public class ViaFabricPlusGameProfileFetcher extends GameProfileFetcher { public class ViaFabricPlusGameProfileFetcher extends GameProfileFetcher {
public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY); private static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY);
public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService(); private static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService();
public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository(); private static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository();
@Override @Override
public UUID loadMojangUUID(String playerName) throws Exception { public UUID loadMojangUUID(String playerName) throws Exception {
@ -61,17 +62,16 @@ public class ViaFabricPlusGameProfileFetcher extends GameProfileFetcher {
@Override @Override
public GameProfile loadGameProfile(UUID uuid) { public GameProfile loadGameProfile(UUID uuid) {
final var result = SESSION_SERVICE.fetchProfile(uuid, true); final ProfileResult result = SESSION_SERVICE.fetchProfile(uuid, true);
if (result == null) throw new ProfileNotFoundException(); if (result == null) throw new ProfileNotFoundException();
final var profile = result.profile(); final var authLibProfile = result.profile();
final var gameProfile = new GameProfile(profile.getName(), profile.getId()); final var mcProfile = new GameProfile(authLibProfile.getName(), authLibProfile.getId());
for (final var entry : profile.getProperties().entries()) { for (final var entry : authLibProfile.getProperties().entries()) {
final Property prop = entry.getValue(); mcProfile.addProperty(new GameProfile.Property(entry.getValue().name(), entry.getValue().value(), entry.getValue().signature()));
gameProfile.addProperty(new GameProfile.Property(prop.name(), prop.value(), prop.signature()));
} }
return gameProfile; return mcProfile;
} }
} }

View File

@ -31,12 +31,11 @@ import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.provider
public class ViaFabricPlusOldAuthProvider extends OldAuthProvider { public class ViaFabricPlusOldAuthProvider extends OldAuthProvider {
@Override @Override
public void sendAuthRequest(UserConnection user, String serverId) throws Throwable { public void sendAuthRequest(UserConnection user, String serverId) {
if (!AuthenticationSettings.global().verifySessionForOnlineModeServers.getValue()) return; if (!AuthenticationSettings.global().verifySessionForOnlineModeServers.getValue()) return;
try { try {
final var mc = MinecraftClient.getInstance(); final var mc = MinecraftClient.getInstance();
mc.getSessionService().joinServer(mc.getSession().getUuidOrNull(), mc.getSession().getAccessToken(), serverId); mc.getSessionService().joinServer(mc.getSession().getUuidOrNull(), mc.getSession().getAccessToken(), serverId);
} catch (Exception e) { } catch (Exception e) {
user.getChannel().attr(ProtocolHack.CLIENT_CONNECTION_ATTRIBUTE_KEY).get().disconnect(ChatUtil.prefixText(Text.translatable("authentication.viafabricplus.failed_to_verify_session"))); user.getChannel().attr(ProtocolHack.CLIENT_CONNECTION_ATTRIBUTE_KEY).get().disconnect(ChatUtil.prefixText(Text.translatable("authentication.viafabricplus.failed_to_verify_session")));

View File

@ -29,9 +29,9 @@ public class ViaFabricPlusBaseVersionProvider extends BaseVersionProvider {
public int getClosestServerProtocol(UserConnection connection) throws Exception { public int getClosestServerProtocol(UserConnection connection) throws Exception {
if (connection.isClientSide()) { if (connection.isClientSide()) {
return connection.getChannel().attr(ProtocolHack.TARGET_VERSION_ATTRIBUTE_KEY).get().getVersion(); return connection.getChannel().attr(ProtocolHack.TARGET_VERSION_ATTRIBUTE_KEY).get().getVersion();
} else {
return super.getClosestServerProtocol(connection);
} }
return super.getClosestServerProtocol(connection);
} }
} }

View File

@ -22,6 +22,7 @@ package de.florianmichael.viafabricplus.protocolhack.impl.provider.viaversion;
import com.viaversion.viaversion.api.minecraft.signature.SignableCommandArgumentsProvider; import com.viaversion.viaversion.api.minecraft.signature.SignableCommandArgumentsProvider;
import com.viaversion.viaversion.util.Pair; import com.viaversion.viaversion.util.Pair;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.argument.SignedArgumentList; import net.minecraft.command.argument.SignedArgumentList;
import java.util.Collections; import java.util.Collections;
@ -31,16 +32,17 @@ public class ViaFabricPlusCommandArgumentsProvider extends SignableCommandArgume
@Override @Override
public List<Pair<String, String>> getSignableArguments(String command) { public List<Pair<String, String>> getSignableArguments(String command) {
final var network = MinecraftClient.getInstance().getNetworkHandler(); final ClientPlayNetworkHandler network = MinecraftClient.getInstance().getNetworkHandler();
if (network != null) { if (network != null) {
return SignedArgumentList.of( return SignedArgumentList.of(
network.getCommandDispatcher().parse(command, network.getCommandSource())). network.getCommandDispatcher().parse(command, network.getCommandSource())).
arguments().stream(). arguments().stream().
map(function -> new Pair<>(function.getNodeName(), function.value())). map(function -> new Pair<>(function.getNodeName(), function.value())).
toList(); toList();
} else {
return Collections.emptyList();
} }
return Collections.emptyList();
} }
} }

View File

@ -27,15 +27,16 @@ import net.minecraft.item.ItemStack;
import net.raphimc.vialoader.util.VersionEnum; import net.raphimc.vialoader.util.VersionEnum;
public class ViaFabricPlusHandItemProvider extends HandItemProvider { public class ViaFabricPlusHandItemProvider extends HandItemProvider {
public static ItemStack lastUsedItem = null; public static ItemStack lastUsedItem = null;
@Override @Override
public Item getHandItem(UserConnection info) { public Item getHandItem(UserConnection info) {
if (lastUsedItem == null || lastUsedItem.isEmpty()) { if (lastUsedItem != null && !lastUsedItem.isEmpty()) {
return ItemTranslator.mcToVia(lastUsedItem, VersionEnum.r1_8);
} else {
return null; return null;
} }
return ItemTranslator.mcToVia(lastUsedItem, VersionEnum.r1_8);
} }
} }

View File

@ -33,9 +33,9 @@ public class ViaFabricPlusPlayerLookTargetProvider extends PlayerLookTargetProvi
if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult blockHitResult) { if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult blockHitResult) {
final BlockPos pos = blockHitResult.getBlockPos(); final BlockPos pos = blockHitResult.getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ()); return new Position(pos.getX(), pos.getY(), pos.getZ());
} else {
return null;
} }
return null;
} }
} }

View File

@ -109,11 +109,11 @@ public class ItemTranslator {
wrapper.read(Type.UNSIGNED_BYTE); // sync id wrapper.read(Type.UNSIGNED_BYTE); // sync id
wrapper.read(Type.VAR_INT); // revision wrapper.read(Type.VAR_INT); // revision
wrapper.read(Type.SHORT); // slot wrapper.read(Type.SHORT); // slot
final var viaItem = wrapper.read(Type.ITEM1_13_2); // item final Item viaItem = wrapper.read(Type.ITEM1_13_2); // item
final ItemStack stack = new ItemStack(Registries.ITEM.get(viaItem.identifier())); final ItemStack mcItem = new ItemStack(Registries.ITEM.get(viaItem.identifier()));
stack.setCount(viaItem.amount()); mcItem.setCount(viaItem.amount());
stack.setDamage(viaItem.data()); mcItem.setDamage(viaItem.data());
return stack; return mcItem;
} catch (Throwable t) { } catch (Throwable t) {
ViaFabricPlus.global().getLogger().error("Error converting ViaVersion b1.8 item to native item stack", t); ViaFabricPlus.global().getLogger().error("Error converting ViaVersion b1.8 item to native item stack", t);
return ItemStack.EMPTY; return ItemStack.EMPTY;

View File

@ -43,7 +43,7 @@ public class TextComponentTranslator {
*/ */
public static Tag via1_14toViaLatest(final JsonElement component) { public static Tag via1_14toViaLatest(final JsonElement component) {
try { try {
var wrapper = PacketWrapper.create(ClientboundPackets1_14.OPEN_WINDOW, DUMMY_USER_CONNECTION); final PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_14.OPEN_WINDOW, DUMMY_USER_CONNECTION);
wrapper.write(Type.VAR_INT, 1); // window id wrapper.write(Type.VAR_INT, 1); // window id
wrapper.write(Type.VAR_INT, 0); // type id wrapper.write(Type.VAR_INT, 0); // type id
wrapper.write(Type.COMPONENT, component); // title wrapper.write(Type.COMPONENT, component); // title

View File

@ -22,6 +22,7 @@ package de.florianmichael.viafabricplus.screen;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -67,14 +68,14 @@ public abstract class VFPListEntry extends AlwaysSelectedEntryListWidget.Entry<V
public void renderScrollableText(final Text name, final int offset) { public void renderScrollableText(final Text name, final int offset) {
final var font = MinecraftClient.getInstance().textRenderer; final var font = MinecraftClient.getInstance().textRenderer;
final var fontWidth = font.getWidth(name); final int fontWidth = font.getWidth(name);
final var textY = entryHeight / 2 - font.fontHeight / 2; final int textY = entryHeight / 2 - font.fontHeight / 2;
if (fontWidth > (entryWidth - offset)) { if (fontWidth > (entryWidth - offset)) {
final var time = (double) Util.getMeasuringTimeMs() / 1000.0; final double time = (double) Util.getMeasuringTimeMs() / 1000.0;
final var interpolateEnd = fontWidth - (entryWidth - offset - (SCISSORS_OFFSET + SLOT_MARGIN)); final double interpolateEnd = fontWidth - (entryWidth - offset - (SCISSORS_OFFSET + SLOT_MARGIN));
final var interpolatedValue = Math.sin((Math.PI / 2) * Math.cos(Math.PI * 2 * time / Math.max((double) interpolateEnd * 0.5, 3.0))) / 2.0 + 0.5; final double interpolatedValue = Math.sin((Math.PI / 2) * Math.cos(Math.PI * 2 * time / Math.max(interpolateEnd * 0.5, 3.0))) / 2.0 + 0.5;
context.enableScissor(x, y, x + entryWidth - offset - SCISSORS_OFFSET, y + entryHeight); context.enableScissor(x, y, x + entryWidth - offset - SCISSORS_OFFSET, y + entryHeight);
context.drawTextWithShadow(font, name, SLOT_MARGIN - (int) MathHelper.lerp(interpolatedValue, 0.0, interpolateEnd), textY, -1); context.drawTextWithShadow(font, name, SLOT_MARGIN - (int) MathHelper.lerp(interpolatedValue, 0.0, interpolateEnd), textY, -1);
@ -109,7 +110,7 @@ public abstract class VFPListEntry extends AlwaysSelectedEntryListWidget.Entry<V
this.entryWidth = entryWidth; this.entryWidth = entryWidth;
this.entryHeight = entryHeight; this.entryHeight = entryHeight;
final var matrices = context.getMatrices(); final MatrixStack matrices = context.getMatrices();
matrices.push(); matrices.push();
matrices.translate(x, y, 0); matrices.translate(x, y, 0);

View File

@ -40,9 +40,10 @@ import net.minecraft.util.Formatting;
import java.util.List; import java.util.List;
public class BetaCraftScreen extends VFPScreen { public class BetaCraftScreen extends VFPScreen {
public static BCServerList SERVER_LIST;
public static final BetaCraftScreen INSTANCE = new BetaCraftScreen(); public static final BetaCraftScreen INSTANCE = new BetaCraftScreen();
public static BCServerList SERVER_LIST;
private static final String BETA_CRAFT_SERVER_LIST_URL = "https://betacraft.uk/serverlist/"; private static final String BETA_CRAFT_SERVER_LIST_URL = "https://betacraft.uk/serverlist/";
protected BetaCraftScreen() { protected BetaCraftScreen() {

View File

@ -36,6 +36,7 @@ import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ClassiCubeLoginScreen extends VFPScreen { public class ClassiCubeLoginScreen extends VFPScreen {
public static final ClassiCubeLoginScreen INSTANCE = new ClassiCubeLoginScreen(); public static final ClassiCubeLoginScreen INSTANCE = new ClassiCubeLoginScreen();
public ClassiCubeLoginScreen() { public ClassiCubeLoginScreen() {

View File

@ -33,6 +33,7 @@ import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ClassiCubeMFAScreen extends VFPScreen { public class ClassiCubeMFAScreen extends VFPScreen {
public static final ClassiCubeMFAScreen INSTANCE = new ClassiCubeMFAScreen(); public static final ClassiCubeMFAScreen INSTANCE = new ClassiCubeMFAScreen();
public ClassiCubeMFAScreen() { public ClassiCubeMFAScreen() {

View File

@ -47,9 +47,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ClassiCubeServerListScreen extends VFPScreen { public class ClassiCubeServerListScreen extends VFPScreen {
public static final List<CCServerInfo> SERVER_LIST = new ArrayList<>();
public static final ClassiCubeServerListScreen INSTANCE = new ClassiCubeServerListScreen(); public static final ClassiCubeServerListScreen INSTANCE = new ClassiCubeServerListScreen();
public static final List<CCServerInfo> SERVER_LIST = new ArrayList<>();
private static final String CLASSICUBE_SERVER_LIST_URL = "https://www.classicube.net/server/list/"; private static final String CLASSICUBE_SERVER_LIST_URL = "https://www.classicube.net/server/list/";
public static void open(final Screen prevScreen, final LoginProcessHandler loginProcessHandler) { public static void open(final Screen prevScreen, final LoginProcessHandler loginProcessHandler) {

View File

@ -52,7 +52,7 @@ public class BooleanSettingRenderer extends VFPListEntry {
final Text text = this.value.getValue() ? Text.translatable("base.viafabricplus.on") : Text.translatable("base.viafabricplus.off"); final Text text = this.value.getValue() ? Text.translatable("base.viafabricplus.on") : Text.translatable("base.viafabricplus.off");
final var offset = textRenderer.getWidth(text) + 6; final int offset = textRenderer.getWidth(text) + 6;
renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset); renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset);
context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, this.value.getValue() ? Color.GREEN.getRGB() : Color.RED.getRGB()); context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, this.value.getValue() ? Color.GREEN.getRGB() : Color.RED.getRGB());

View File

@ -27,6 +27,7 @@ import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ButtonSettingRenderer extends VFPListEntry { public class ButtonSettingRenderer extends VFPListEntry {
private final ButtonSetting value; private final ButtonSetting value;
public ButtonSettingRenderer(ButtonSetting value) { public ButtonSettingRenderer(ButtonSetting value) {

View File

@ -51,7 +51,7 @@ public class ModeSettingRenderer extends VFPListEntry {
public void mappedRender(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { public void mappedRender(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
final var offset = textRenderer.getWidth(this.value.getValue()) + 6; final int offset = textRenderer.getWidth(this.value.getValue()) + 6;
renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset); renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset);
context.drawTextWithShadow(textRenderer, this.value.getValue(), entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, -1); context.drawTextWithShadow(textRenderer, this.value.getValue(), entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, -1);

View File

@ -28,6 +28,7 @@ import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
public class TitleRenderer extends VFPListEntry { public class TitleRenderer extends VFPListEntry {
private final Text name; private final Text name;
public TitleRenderer(Text name) { public TitleRenderer(Text name) {

View File

@ -54,7 +54,7 @@ public class VersionedBooleanSettingRenderer extends VFPListEntry {
final Text text = Text.translatable("base.viafabricplus." + (this.value.isAuto() ? "auto" : this.value.isEnabled() ? "on" : "off")); final Text text = Text.translatable("base.viafabricplus." + (this.value.isAuto() ? "auto" : this.value.isEnabled() ? "on" : "off"));
Color color = this.value.isAuto() ? Color.ORANGE : this.value.isEnabled() ? Color.GREEN : Color.RED; Color color = this.value.isAuto() ? Color.ORANGE : this.value.isEnabled() ? Color.GREEN : Color.RED;
final var offset = textRenderer.getWidth(text) + 6; final int offset = textRenderer.getWidth(text) + 6;
renderScrollableText(Text.of(Formatting.GRAY + this.value.getName().getString() + " " + Formatting.RESET + this.value.getProtocolRange().toString()), offset); renderScrollableText(Text.of(Formatting.GRAY + this.value.getName().getString() + " " + Formatting.RESET + this.value.getProtocolRange().toString()), offset);
context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, color.getRGB()); context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, color.getRGB());

View File

@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class SettingsManager { public class SettingsManager {
private final List<SettingGroup> groups = new ArrayList<>(); private final List<SettingGroup> groups = new ArrayList<>();
public SettingsManager() { public SettingsManager() {

View File

@ -32,6 +32,7 @@ import net.minecraft.text.Text;
* @param <T> The type of the setting. * @param <T> The type of the setting.
*/ */
public abstract class AbstractSetting<T> { public abstract class AbstractSetting<T> {
private final MutableText name; private final MutableText name;
private final T defaultValue; private final T defaultValue;

View File

@ -28,6 +28,7 @@ import net.minecraft.text.MutableText;
import java.util.Arrays; import java.util.Arrays;
public class ModeSetting extends AbstractSetting<MutableText> { public class ModeSetting extends AbstractSetting<MutableText> {
private final MutableText[] options; private final MutableText[] options;
public ModeSetting(SettingGroup parent, MutableText name, MutableText... options) { public ModeSetting(SettingGroup parent, MutableText name, MutableText... options) {

View File

@ -29,6 +29,7 @@ import java.util.List;
* @see AbstractSetting * @see AbstractSetting
*/ */
public class SettingGroup { public class SettingGroup {
private final List<AbstractSetting<?>> settings = new ArrayList<>(); private final List<AbstractSetting<?>> settings = new ArrayList<>();
private final Text name; private final Text name;

View File

@ -27,6 +27,7 @@ import net.minecraft.text.MutableText;
import net.raphimc.vialoader.util.VersionRange; import net.raphimc.vialoader.util.VersionRange;
public class VersionedBooleanSetting extends AbstractSetting<Integer> { public class VersionedBooleanSetting extends AbstractSetting<Integer> {
private static final int AUTO_INDEX = 2; private static final int AUTO_INDEX = 2;
private static final int DISABLED_INDEX = 1; private static final int DISABLED_INDEX = 1;
private static final int ENABLED_INDEX = 0; private static final int ENABLED_INDEX = 0;

View File

@ -24,6 +24,7 @@ import de.florianmichael.viafabricplus.settings.base.SettingGroup;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class AuthenticationSettings extends SettingGroup { public class AuthenticationSettings extends SettingGroup {
private static final AuthenticationSettings instance = new AuthenticationSettings(); private static final AuthenticationSettings instance = new AuthenticationSettings();
public final BooleanSetting useBetaCraftAuthentication = new BooleanSetting(this, Text.translatable("authentication_settings.viafabricplus.use_beta_craft_authentication"), true); public final BooleanSetting useBetaCraftAuthentication = new BooleanSetting(this, Text.translatable("authentication_settings.viafabricplus.use_beta_craft_authentication"), true);

View File

@ -45,12 +45,10 @@ public class BedrockSettings extends SettingGroup {
@Override @Override
public MutableText displayValue() { public MutableText displayValue() {
final var bedrockSession = ViaFabricPlus.global().getSaveManager().getAccountsSave().getBedrockAccount(); final var account = ViaFabricPlus.global().getSaveManager().getAccountsSave().getBedrockAccount();
if (bedrockSession == null) { if (account == null) return super.displayValue();
return super.displayValue();
}
return Text.literal("Bedrock account: " + bedrockSession.getMcChain().getDisplayName()); return Text.literal("Bedrock account: " + account.getMcChain().getDisplayName());
} }
}; };
public final BooleanSetting openPromptGUIToConfirmTransfer = new BooleanSetting(this, Text.translatable("bedrock_settings.viafabricplus.confirm_transfer_server_prompt"), true); public final BooleanSetting openPromptGUIToConfirmTransfer = new BooleanSetting(this, Text.translatable("bedrock_settings.viafabricplus.confirm_transfer_server_prompt"), true);

View File

@ -27,6 +27,7 @@ import net.raphimc.vialoader.util.VersionEnum;
import net.raphimc.vialoader.util.VersionRange; import net.raphimc.vialoader.util.VersionRange;
public class DebugSettings extends SettingGroup { public class DebugSettings extends SettingGroup {
private static final DebugSettings instance = new DebugSettings(); private static final DebugSettings instance = new DebugSettings();
public final BooleanSetting queueConfigPackets = new BooleanSetting(this, Text.translatable("debug_settings.viafabricplus.queue_config_packets"), true); public final BooleanSetting queueConfigPackets = new BooleanSetting(this, Text.translatable("debug_settings.viafabricplus.queue_config_packets"), true);

View File

@ -26,6 +26,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class GeneralSettings extends SettingGroup { public class GeneralSettings extends SettingGroup {
private static final GeneralSettings instance = new GeneralSettings(); private static final GeneralSettings instance = new GeneralSettings();
public final ModeSetting multiplayerScreenButtonOrientation = new ModeSetting(this, Text.translatable("general_settings.viafabricplus.multiplayer_screen_button_orientation"), 1, public final ModeSetting multiplayerScreenButtonOrientation = new ModeSetting(this, Text.translatable("general_settings.viafabricplus.multiplayer_screen_button_orientation"), 1,

View File

@ -26,6 +26,7 @@ import net.raphimc.vialoader.util.VersionEnum;
import net.raphimc.vialoader.util.VersionRange; import net.raphimc.vialoader.util.VersionRange;
public class VisualSettings extends SettingGroup { public class VisualSettings extends SettingGroup {
private static final VisualSettings instance = new VisualSettings(); private static final VisualSettings instance = new VisualSettings();
// 1.20.3 -> 1.20.2 and 1.16 -> 1.15.2 // 1.20.3 -> 1.20.2 and 1.16 -> 1.15.2