From 70734574837a1234fea97f1a9e62c385b2ecba30 Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Wed, 21 Aug 2024 08:53:45 +0200 Subject: [PATCH] Minecraft 1.20.6, Java 21 --- .github/workflows/build.yml | 4 +- README.md | 4 +- build.gradle | 5 +- settings.gradle | 1 + viaforge-mc1206/gradle.properties | 1 + .../florianmichael/viaforge/ViaForge1206.java | 73 ++++++++ .../viaforge/gui/GuiProtocolSelector.java | 167 ++++++++++++++++++ .../mixin/MixinDebugScreenOverlay.java | 45 +++++ .../mixin/MixinDirectJoinServerScreen.java | 51 ++++++ .../viaforge/mixin/MixinEditServerScreen.java | 68 +++++++ .../mixin/MixinJoinMultiplayerScreen.java | 51 ++++++ .../viaforge/mixin/MixinServerData.java | 70 ++++++++ .../viaforge/mixin/MixinTitleScreen.java | 51 ++++++ ...ixinClientHandshakePacketListenerImpl.java | 59 +++++++ .../mixin/connect/MixinConnectScreen_1.java | 50 ++++++ .../mixin/connect/MixinConnection.java | 99 +++++++++++ .../mixin/connect/MixinConnection_1.java | 39 ++++ .../connect/MixinServerStatusPinger.java | 61 +++++++ .../mixin/fixes/MixinLocalPlayer.java | 56 ++++++ .../provider/ViaForgeGameProfileFetcher.java | 76 ++++++++ .../src/main/resources/META-INF/mods.toml | 16 ++ .../resources/mixins.viaforge-mc1206.json | 24 +++ 22 files changed, 1065 insertions(+), 6 deletions(-) create mode 100644 viaforge-mc1206/gradle.properties create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/ViaForge1206.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/gui/GuiProtocolSelector.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDebugScreenOverlay.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDirectJoinServerScreen.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinEditServerScreen.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinJoinMultiplayerScreen.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinServerData.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinTitleScreen.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinClientHandshakePacketListenerImpl.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnectScreen_1.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection_1.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinServerStatusPinger.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/fixes/MixinLocalPlayer.java create mode 100644 viaforge-mc1206/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java create mode 100644 viaforge-mc1206/src/main/resources/META-INF/mods.toml create mode 100644 viaforge-mc1206/src/main/resources/mixins.viaforge-mc1206.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5704ce0..3244763 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,10 +9,10 @@ jobs: uses: actions/checkout@v4 - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: 'temurin' check-latest: true - name: Cache Dependencies diff --git a/README.md b/README.md index 21debb6..8d4c554 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ See [this project](https://github.com/ViaVersionMCP/ViaMCP) for a copy-paste sol 2. Run `./gradlew build` in the root directory of the repository. 3. The compiled jar files can be found in `viaforge-mc/build/libs`. -Note: Build scripts are made to be run using Java 17. +Note: Build scripts are made to be run using Java 21. ## Other ViaVersion Mods / Platforms @@ -52,4 +52,4 @@ ViaForge - https://modrinth.com/mod/viaforge/
ViaProxy (App) - https://github.com/ViaVersion/ViaProxy/#readme
ViaaaS (Proxy) - https://github.com/ViaVersion/ViaaaS#readme
-For a more detailed summary see https://viaversion.com/suite \ No newline at end of file +For a more detailed summary see https://viaversion.com \ No newline at end of file diff --git a/build.gradle b/build.gradle index a1bbf38..82f36ee 100644 --- a/build.gradle +++ b/build.gradle @@ -21,8 +21,9 @@ allprojects { apply plugin: "xyz.wagyourtail.jvmdowngrader" java { - // Minecraft 1.17+ required Java 16/17 to compile - toolchain.languageVersion = JavaLanguageVersion.of(17) + // Minecraft 1.17+ required Java 17 to compile, + // Minecraft 1.20.5+ required Java 21 to compile + toolchain.languageVersion = JavaLanguageVersion.of(21) } // We define the configuration here so we can use it across all conventions and platforms diff --git a/settings.gradle b/settings.gradle index c0d9758..b07ea65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,3 +11,4 @@ include "viaforge-mc1182" include "viaforge-mc1192" include "viaforge-mc1194" include "viaforge-mc1204" +include "viaforge-mc1206" \ No newline at end of file diff --git a/viaforge-mc1206/gradle.properties b/viaforge-mc1206/gradle.properties new file mode 100644 index 0000000..378f4e0 --- /dev/null +++ b/viaforge-mc1206/gradle.properties @@ -0,0 +1 @@ +forge_version=1.20.6-50.1.12 \ No newline at end of file diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/ViaForge1206.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/ViaForge1206.java new file mode 100644 index 0000000..356072b --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/ViaForge1206.java @@ -0,0 +1,73 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge; + +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.platform.VFPlatform; +import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher; +import net.minecraft.SharedConstants; +import net.minecraft.client.Minecraft; +import net.minecraft.client.User; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher; + +import java.io.File; +import java.util.function.Supplier; + +@Mod("viaforge") +public class ViaForge1206 implements VFPlatform { + + public ViaForge1206() { + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onInit); + } + + private void onInit(FMLCommonSetupEvent event) { + ViaForgeCommon.init(this); + } + + @Override + public int getGameVersion() { + return SharedConstants.getProtocolVersion(); + } + + @Override + public Supplier isSingleplayer() { + return () -> Minecraft.getInstance().isSingleplayer(); + } + + @Override + public File getLeadingDirectory() { + return Minecraft.getInstance().gameDirectory; + } + + @Override + public void joinServer(String serverId) throws Throwable { + final User session = Minecraft.getInstance().getUser(); + + Minecraft.getInstance().getMinecraftSessionService().joinServer(session.getProfileId(), session.getAccessToken(), serverId); + } + + @Override + public GameProfileFetcher getGameProfileFetcher() { + return new ViaForgeGameProfileFetcher(); + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/gui/GuiProtocolSelector.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/gui/GuiProtocolSelector.java new file mode 100644 index 0000000..a771d80 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/gui/GuiProtocolSelector.java @@ -0,0 +1,167 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.gui; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.util.DumpUtil; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.ObjectSelectionList; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.raphimc.vialoader.util.ProtocolVersionList; +import org.lwjgl.glfw.GLFW; + +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +public class GuiProtocolSelector extends Screen { + + public final Screen parent; + public final boolean simple; + public final FinishedCallback finishedCallback; + + private String status; + private long time; + + public static void open(final Minecraft minecraft) { // Bypass for some weird bytecode instructions errors in Forge + minecraft.setScreen(new GuiProtocolSelector(minecraft.screen)); + } + + public GuiProtocolSelector(final Screen parent) { + this(parent, false, (version, unused) -> { + // Default action is to set the target version and go back to the parent screen. + ViaForgeCommon.getManager().setTargetVersion(version); + }); + } + + public GuiProtocolSelector(final Screen parent, final boolean simple, final FinishedCallback finishedCallback) { + super(Component.literal("ViaForge Protocol Selector")); + this.parent = parent; + this.simple = simple; + this.finishedCallback = finishedCallback; + } + + @Override + public void init() { + super.init(); + addRenderableWidget(Button.builder(Component.literal("<-"), b -> minecraft.setScreen(parent)).bounds(5, height - 25, 20, 20).build()); + if (!this.simple) { + addRenderableWidget(Button.builder(Component.literal("Create dump"), b -> { + try { + minecraft.keyboardHandler.setClipboard(DumpUtil.postDump(UUID.randomUUID()).get()); + setStatus(ChatFormatting.GREEN + "Dump created and copied to clipboard"); + } catch (InterruptedException | ExecutionException e) { + setStatus(ChatFormatting.RED + "Failed to create dump: " + e.getMessage()); + } + }).bounds(width - 105, 5, 100, 20).build()); + addRenderableWidget(Button.builder(Component.literal("Reload configs"), b -> Via.getManager().getConfigurationProvider().reloadConfigs()).bounds(width - 105, height - 25, 100, 20).build()); + } + + addRenderableWidget(new SlotList(minecraft, width, height, 3 + 3 /* start offset */ + (font.lineHeight + 2) * 3 /* title is 2 */, 30, font.lineHeight + 2)); + } + + public void setStatus(final String status) { + this.status = status; + this.time = System.currentTimeMillis(); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int actions) { + if (keyCode == GLFW.GLFW_KEY_ESCAPE) { + minecraft.setScreen(parent); + } + return super.keyPressed(keyCode, scanCode, actions); + } + + @Override + public void render(GuiGraphics graphics, int p_230430_2_, int p_230430_3_, float p_230430_4_) { + if (System.currentTimeMillis() - this.time >= 10_000) { + this.status = null; + } + + super.render(graphics, p_230430_2_, p_230430_3_, p_230430_4_); + + final var pose = graphics.pose(); + + pose.pushPose(); + pose.scale(2.0F, 2.0F, 2.0F); + graphics.drawCenteredString(font, ChatFormatting.GOLD + "ViaForge", width / 4, 3, 16777215); + pose.popPose(); + + graphics.drawCenteredString(font, "https://github.com/ViaVersion/ViaForge", width / 2, (font.lineHeight + 2) * 2 + 3, -1); + graphics.drawString(font, status != null ? status : "Discord: florianmichael", 3, 3, -1); + } + + class SlotList extends ObjectSelectionList { + + public SlotList(Minecraft client, int width, int height, int top, int bottom, int slotHeight) { + super(client, width, height - top - bottom, top, slotHeight); + + for (ProtocolVersion version : ProtocolVersionList.getProtocolsNewToOld()) { + addEntry(new SlotEntry(version)); + } + } + + public class SlotEntry extends Entry { + + private final ProtocolVersion ProtocolVersion; + + public SlotEntry(ProtocolVersion ProtocolVersion) { + this.ProtocolVersion = ProtocolVersion; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + GuiProtocolSelector.this.finishedCallback.finished(ProtocolVersion, GuiProtocolSelector.this.parent); + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public Component getNarration() { + return Component.literal(ProtocolVersion.getName()); + } + + @Override + public void render(GuiGraphics graphics, int p_93524_, int y, int p_93526_, int p_93527_, int p_93528_, int p_93529_, int p_93530_, boolean p_93531_, float p_93532_) { + final ProtocolVersion targetVersion = ViaForgeCommon.getManager().getTargetVersion(); + + String color; + if (targetVersion == ProtocolVersion) { + color = GuiProtocolSelector.this.simple ? ChatFormatting.GOLD.toString() : ChatFormatting.GREEN.toString(); + } else { + color = GuiProtocolSelector.this.simple ? ChatFormatting.WHITE.toString() : ChatFormatting.DARK_RED.toString(); + } + + graphics.drawCenteredString(Minecraft.getInstance().font, color + ProtocolVersion.getName(), width / 2, y, -1); + } + } + } + + public interface FinishedCallback { + + void finished(final ProtocolVersion version, final Screen parent); + + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDebugScreenOverlay.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDebugScreenOverlay.java new file mode 100644 index 0000000..9e9ca9a --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDebugScreenOverlay.java @@ -0,0 +1,45 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.minecraft.client.gui.components.DebugScreenOverlay; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(DebugScreenOverlay.class) +public class MixinDebugScreenOverlay { + + @Inject(method = "getSystemInformation", at = @At(value = "TAIL")) + public void addViaForgeVersion(CallbackInfoReturnable> cir) { + final ViaForgeCommon common = ViaForgeCommon.getManager(); + final ProtocolVersion version = ViaForgeCommon.getManager().getTargetVersion(); + + if (common.getConfig().isShowProtocolVersionInF3() && version != common.getNativeVersion() && !common.getPlatform().isSingleplayer().get()) { + cir.getReturnValue().add(""); + cir.getReturnValue().add("ViaForge: " + version.toString()); + } + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDirectJoinServerScreen.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDirectJoinServerScreen.java new file mode 100644 index 0000000..8a0f2fe --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinDirectJoinServerScreen.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import com.viaversion.viaversion.util.Pair; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.platform.ViaForgeConfig; +import de.florianmichael.viaforge.gui.GuiProtocolSelector; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.DirectJoinServerScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(DirectJoinServerScreen.class) +public class MixinDirectJoinServerScreen extends Screen { + + public MixinDirectJoinServerScreen(Component title) { + super(title); + } + + @Inject(method = "init", at = @At("RETURN")) + public void hookViaForgeButton(CallbackInfo ci) { + final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig(); + if (config.isShowDirectConnectButton()) { + final Pair pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height); + + addRenderableWidget(Button.builder(Component.literal("ViaForge"), b -> GuiProtocolSelector.open(minecraft)).bounds(pos.key(), pos.value(), 100, 20).build()); + } + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinEditServerScreen.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinEditServerScreen.java new file mode 100644 index 0000000..aad945e --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinEditServerScreen.java @@ -0,0 +1,68 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import com.viaversion.viaversion.util.Pair; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.gui.ExtendedServerData; +import de.florianmichael.viaforge.common.platform.ViaForgeConfig; +import de.florianmichael.viaforge.gui.GuiProtocolSelector; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.EditServerScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.network.chat.Component; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +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(EditServerScreen.class) +public class MixinEditServerScreen extends Screen { + + @Shadow + @Final + private ServerData serverData; + + public MixinEditServerScreen(Component title) { + super(title); + } + + @Inject(method = "init", at = @At("RETURN")) + public void initGui(CallbackInfo ci) { + final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig(); + + if (config.isShowAddServerButton()) { + final Pair pos = config.getAddServerScreenButtonPosition().getPosition(this.width, this.height); + + final ProtocolVersion target = ((ExtendedServerData) serverData).viaForge$getVersion(); + addRenderableWidget(Button.builder(Component.literal(target != null ? target.getName() : "Set Version"), b -> { + minecraft.setScreen(new GuiProtocolSelector(this, true, (version, parent) -> { + // Set version and go back to the parent screen. + ((ExtendedServerData) serverData).viaForge$setVersion(version); + minecraft.setScreen(parent); + })); + }).bounds(pos.key(), pos.value(), 100, 20).build()); + } + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinJoinMultiplayerScreen.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinJoinMultiplayerScreen.java new file mode 100644 index 0000000..c38ec5c --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinJoinMultiplayerScreen.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import com.viaversion.viaversion.util.Pair; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.platform.ViaForgeConfig; +import de.florianmichael.viaforge.gui.GuiProtocolSelector; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(JoinMultiplayerScreen.class) +public class MixinJoinMultiplayerScreen extends Screen { + + public MixinJoinMultiplayerScreen(Component title) { + super(title); + } + + @Inject(method = "init", at = @At("RETURN")) + public void hookViaForgeButton(CallbackInfo ci) { + final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig(); + if (config.isShowMainMenuButton()) { + final Pair pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height); + + addRenderableWidget(Button.builder(Component.literal("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)).bounds(pos.key(), pos.value(), 100, 20).build()); + } + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinServerData.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinServerData.java new file mode 100644 index 0000000..3a019e0 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinServerData.java @@ -0,0 +1,70 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import de.florianmichael.viaforge.common.gui.ExtendedServerData; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.nbt.CompoundTag; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +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.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(ServerData.class) +public class MixinServerData implements ExtendedServerData { + + @Unique + private ProtocolVersion viaForge$version; + + @Inject(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/CompoundTag;putString(Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) + public void saveVersion(CallbackInfoReturnable cir, CompoundTag compoundtag) { + if (viaForge$version != null) { + compoundtag.putString("viaForge$version", viaForge$version.getName()); + } + } + + @Inject(method = "read", at = @At(value = "TAIL")) + private static void getVersion(CompoundTag compoundnbt, CallbackInfoReturnable cir) { + if (compoundnbt.contains("viaForge$version")) { + ((ExtendedServerData) cir.getReturnValue()).viaForge$setVersion(ProtocolVersion.getClosest(compoundnbt.getString("viaForge$version"))); + } + } + + @Inject(method = "copyFrom", at = @At("HEAD")) + public void track(ServerData serverDataIn, CallbackInfo ci) { + if (serverDataIn instanceof ExtendedServerData) { + viaForge$version = ((ExtendedServerData) serverDataIn).viaForge$getVersion(); + } + } + + @Override + public ProtocolVersion viaForge$getVersion() { + return viaForge$version; + } + + @Override + public void viaForge$setVersion(ProtocolVersion version) { + viaForge$version = version; + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinTitleScreen.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinTitleScreen.java new file mode 100644 index 0000000..5cdc49f --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/MixinTitleScreen.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin; + +import com.viaversion.viaversion.util.Pair; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.platform.ViaForgeConfig; +import de.florianmichael.viaforge.gui.GuiProtocolSelector; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class MixinTitleScreen extends Screen { + + public MixinTitleScreen(Component title) { + super(title); + } + + @Inject(method = "init", at = @At("RETURN")) + public void hookViaForgeButton(CallbackInfo ci) { + final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig(); + if (config.isShowMainMenuButton()) { + final Pair pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height); + + addRenderableWidget(Button.builder(Component.literal("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)).bounds(pos.key(), pos.value(), 100, 20).build()); + } + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinClientHandshakePacketListenerImpl.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinClientHandshakePacketListenerImpl.java new file mode 100644 index 0000000..42204e9 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinClientHandshakePacketListenerImpl.java @@ -0,0 +1,59 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.connect; + +import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager; +import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; +import net.minecraft.network.Connection; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.storage.ProtocolMetadataStorage; +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.Redirect; + +import java.util.UUID; + +@SuppressWarnings("DataFlowIssue") +@Mixin(ClientHandshakePacketListenerImpl.class) +public class MixinClientHandshakePacketListenerImpl { + + @Shadow @Final private Connection connection; + + @Redirect(method = "authenticateServer", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/minecraft/MinecraftSessionService;joinServer(Ljava/util/UUID;Ljava/lang/String;Ljava/lang/String;)V")) + public void onlyJoinServerIfPremium(MinecraftSessionService instance, UUID uuid, String authenticationToken, String serverId) throws AuthenticationException { + final VFNetworkManager mixinConnection = (VFNetworkManager) connection; + if (mixinConnection.viaForge$getTrackedVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + final UserConnection user = connection.channel().attr(ViaForgeCommon.VF_VIA_USER).get(); + if (user != null && user.has(ProtocolMetadataStorage.class) && !user.get(ProtocolMetadataStorage.class).authenticate) { + // We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call + // if the server is in offline mode, due the packet changes <-> networking changes + // Minecraft's networking code is bad for us. + return; + } + } + instance.joinServer(uuid, authenticationToken, serverId); + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnectScreen_1.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnectScreen_1.java new file mode 100644 index 0000000..8257ea4 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnectScreen_1.java @@ -0,0 +1,50 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.connect; + +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.gui.ExtendedServerData; +import de.florianmichael.viaforge.common.platform.VersionTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ServerData; +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.Redirect; + +import java.net.InetSocketAddress; +import java.util.Optional; + +@Mixin(targets = "net.minecraft.client.gui.screens.ConnectScreen$1") +public class MixinConnectScreen_1 { + + @Redirect(method = "run", at = @At(value = "INVOKE", target = "Ljava/util/Optional;get()Ljava/lang/Object;")) + public Object trackServerVersion(Optional instance) { + final InetSocketAddress address = (InetSocketAddress) instance.get(); + ProtocolVersion version = ((ExtendedServerData) Minecraft.getInstance().getCurrentServer()).viaForge$getVersion(); + if (version == null) { + version = ViaForgeCommon.getManager().getTargetVersion(); + } + VersionTracker.storeServerProtocolVersion(address.getAddress(), version); + return address; + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection.java new file mode 100644 index 0000000..3f86925 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection.java @@ -0,0 +1,99 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.connect; + +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.platform.VersionTracker; +import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import net.minecraft.network.CipherDecoder; +import net.minecraft.network.CipherEncoder; +import net.minecraft.network.Connection; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import net.raphimc.vialoader.netty.VLLegacyPipeline; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +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.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import javax.crypto.Cipher; +import java.net.InetSocketAddress; + +@Mixin(Connection.class) +public class MixinConnection implements VFNetworkManager { + + @Shadow private Channel channel; + + @Shadow private boolean encrypted; + @Unique + private Cipher viaForge$decryptionCipher; + + @Unique + private ProtocolVersion viaForge$targetVersion; + + @Inject(method = "setupCompression", at = @At("RETURN")) + public void reorderPipeline(int p_129485_, boolean p_182682_, CallbackInfo ci) { + ViaForgeCommon.getManager().reorderCompression(channel); + } + + @Inject(method = "setEncryptionKey", at = @At("HEAD"), cancellable = true) + private void storeEncryptionCiphers(Cipher p_244777_1_, Cipher p_244777_2_, CallbackInfo ci) { + if (viaForge$targetVersion != null && viaForge$targetVersion.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + // Minecraft's encryption code is bad for us, we need to reorder the pipeline + ci.cancel(); + + // Minecraft 1.6.4 supports tile encryption which means the server can only enable one side of the encryption + // So we only enable the encryption side and later enable the decryption side if the 1.7 -> 1.6 protocol + // tells us to do, therefore we need to store the cipher instance. + this.viaForge$decryptionCipher = p_244777_1_; + + // Enabling the encryption side + this.encrypted = true; + this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new CipherEncoder(p_244777_2_)); + } + } + + @Inject(method = "connect", at = @At("HEAD")) + private static void setTargetVersion(InetSocketAddress p_290034_, boolean p_290035_, Connection p_290031_, CallbackInfoReturnable cir) { + final VFNetworkManager mixinConnection = (VFNetworkManager) p_290031_; + mixinConnection.viaForge$setTrackedVersion(VersionTracker.getServerProtocolVersion(p_290034_.getAddress())); + } + + @Override + public void viaForge$setupPreNettyDecryption() { + // Enabling the decryption side for 1.6.4 if the 1.7 -> 1.6 protocol tells us to do + this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "decrypt", new CipherDecoder(this.viaForge$decryptionCipher)); + } + + @Override + public ProtocolVersion viaForge$getTrackedVersion() { + return viaForge$targetVersion; + } + + @Override + public void viaForge$setTrackedVersion(ProtocolVersion version) { + viaForge$targetVersion = version; + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection_1.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection_1.java new file mode 100644 index 0000000..8e0e567 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinConnection_1.java @@ -0,0 +1,39 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.connect; + +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(targets = "net.minecraft.network.Connection$1") +public class MixinConnection_1 { + + @Inject(method = "initChannel", at = @At("TAIL")) + private void hookViaPipeline(Channel p_129552_, CallbackInfo ci) { + final ChannelHandler connection = p_129552_.pipeline().get("packet_handler"); + ViaForgeCommon.getManager().inject(p_129552_, (VFNetworkManager) connection); + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinServerStatusPinger.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinServerStatusPinger.java new file mode 100644 index 0000000..f296a80 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/connect/MixinServerStatusPinger.java @@ -0,0 +1,61 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.connect; + +import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.gui.ExtendedServerData; +import de.florianmichael.viaforge.common.platform.VersionTracker; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.multiplayer.ServerStatusPinger; +import net.minecraft.network.Connection; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.util.debugchart.LocalSampleLogger; +import org.spongepowered.asm.mixin.Mixin; +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 java.net.InetSocketAddress; + +@Mixin(ServerStatusPinger.class) +public class MixinServerStatusPinger { + + @Unique + private ServerData viaForge$serverData; + + @Inject(method = "pingServer", at = @At("HEAD")) + public void trackServerData(ServerData p_105460_, Runnable p_105461_, Runnable p_335024_, CallbackInfo ci) { + viaForge$serverData = p_105460_; + } + + @Redirect(method = "pingServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/Connection;connectToServer(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/debugchart/LocalSampleLogger;)Lnet/minecraft/network/Connection;")) + public Connection trackVersion(InetSocketAddress inetSocketAddress, boolean b, LocalSampleLogger localSampleLogger) { + ProtocolVersion version = ((ExtendedServerData) viaForge$serverData).viaForge$getVersion(); + if (version == null) { + version = ViaForgeCommon.getManager().getTargetVersion(); + } + VersionTracker.storeServerProtocolVersion(inetSocketAddress.getAddress(), version); + viaForge$serverData = null; + + return Connection.connectToServer(inetSocketAddress, b, localSampleLogger); + } + +} diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/fixes/MixinLocalPlayer.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/fixes/MixinLocalPlayer.java new file mode 100644 index 0000000..a2ec4b3 --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/mixin/fixes/MixinLocalPlayer.java @@ -0,0 +1,56 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.mixin.fixes; + +import com.mojang.authlib.GameProfile; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.player.LocalPlayer; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +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.Redirect; + +@Mixin(LocalPlayer.class) +public class MixinLocalPlayer extends AbstractClientPlayer { + + @Shadow private boolean lastOnGround; + + public MixinLocalPlayer(ClientLevel level, GameProfile profile) { + super(level, profile); + } + + @Redirect(method = "sendPosition", at = @At(value = "FIELD", target = "Lnet/minecraft/client/player/LocalPlayer;lastOnGround:Z", ordinal = 0)) + public boolean emulateIdlePacket(LocalPlayer instance) { + if (ViaForgeCommon.getManager().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) { + // <= 1.8 spams the idle packet instead of only sending it when the ground state changes + // So we invert the original logic: + // if (prevOnGround != onGround) sendPacket + // To be like: + // if (!onGround != onGround) sendPacket + // Which is the same as: + // if (true) sendPacket + return !onGround(); + } + return lastOnGround; + } + +} \ No newline at end of file diff --git a/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java new file mode 100644 index 0000000..8a8009b --- /dev/null +++ b/viaforge-mc1206/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java @@ -0,0 +1,76 @@ +/* + * This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge + * Copyright (C) 2021-2024 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.florianmichael.viaforge.provider; + +import com.mojang.authlib.GameProfileRepository; +import com.mojang.authlib.HttpAuthenticationService; +import com.mojang.authlib.ProfileLookupCallback; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.yggdrasil.ProfileNotFoundException; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.model.GameProfile; +import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher; + +import java.net.Proxy; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public class ViaForgeGameProfileFetcher extends GameProfileFetcher { + + public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY); + public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService(); + public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository(); + + @Override + public UUID loadMojangUUID(String playerName) throws Exception { + final CompletableFuture future = new CompletableFuture<>(); + GAME_PROFILE_REPOSITORY.findProfilesByNames(new String[]{playerName}, new ProfileLookupCallback() { + @Override + public void onProfileLookupSucceeded(com.mojang.authlib.GameProfile profile) { + future.complete(profile); + } + + @Override + public void onProfileLookupFailed(String profileName, Exception exception) { + future.completeExceptionally(exception); + } + }); + if (!future.isDone()) { + future.completeExceptionally(new ProfileNotFoundException()); + } + return future.get().getId(); + } + + @Override + public GameProfile loadGameProfile(UUID uuid) throws Exception { + final var result = SESSION_SERVICE.fetchProfile(uuid, true); + if (result == null) throw new ProfileNotFoundException(); + + final var profile = result.profile(); + final var gameProfile = new GameProfile(profile.getName(), profile.getId()); + + for (final var entry : profile.getProperties().entries()) { + final Property prop = entry.getValue(); + gameProfile.addProperty(new GameProfile.Property(prop.name(), prop.value(), prop.signature())); + } + return gameProfile; + } + +} diff --git a/viaforge-mc1206/src/main/resources/META-INF/mods.toml b/viaforge-mc1206/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..a57f55b --- /dev/null +++ b/viaforge-mc1206/src/main/resources/META-INF/mods.toml @@ -0,0 +1,16 @@ +modLoader="javafml" +loaderVersion="[50,)" + +license="GPL-3.0 license" +issueTrackerURL="https://github.com/ViaVersion/ViaForge/issues" +showAsResourcePack=false + +[[mods]] +modId="viaforge" +version="${version}" +displayName="ViaForge" +displayURL="https://github.com/FlorianMichael" +logoFile="icon.png" +credits="Github contributors" +authors="FlorianMichael/EnZaXD" +description="${description}" \ No newline at end of file diff --git a/viaforge-mc1206/src/main/resources/mixins.viaforge-mc1206.json b/viaforge-mc1206/src/main/resources/mixins.viaforge-mc1206.json new file mode 100644 index 0000000..97938ad --- /dev/null +++ b/viaforge-mc1206/src/main/resources/mixins.viaforge-mc1206.json @@ -0,0 +1,24 @@ +{ + "required": true, + "minVersion": "0.7.5", + "compatibilityLevel": "JAVA_8", + "package": "de.florianmichael.viaforge.mixin", + "client": [ + "MixinDebugScreenOverlay", + "MixinDirectJoinServerScreen", + "MixinEditServerScreen", + "MixinJoinMultiplayerScreen", + "MixinServerData", + "MixinTitleScreen", + "connect.MixinClientHandshakePacketListenerImpl", + "connect.MixinConnection", + "connect.MixinConnection_1", + "connect.MixinConnectScreen_1", + "connect.MixinServerStatusPinger", + "fixes.MixinLocalPlayer" + ], + "injectors": { + "defaultRequire": 1 + }, + "refmap": "mixins.viaforge-mc1206.refmap.json" +}