From 3000680ebe78379b004f2f39b0a647995ea00f0f Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Mon, 24 Mar 2025 19:07:54 +0100 Subject: [PATCH 1/2] Port to the release candidate for 1.21.5 Swap the mixin for quick connect, to actually use quick connect directly with a wrap method call. --- gradle.properties | 2 +- settings.gradle | 16 +++++- .../mixin/client/MinecraftMixin.java | 52 ++++++++----------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/gradle.properties b/gradle.properties index 517d723..a815619 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -neoforgeVersion=21.0.158 +neoforgeVersion=21.5.0-alpha.1.21.5-rc1.20250323.193003 neoForge.parchment.minecraftVersion=1.21 neoForge.parchment.mappingsVersion=2024.07.07 diff --git a/settings.gradle b/settings.gradle index 395d9b9..d99c2e4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,8 +5,8 @@ pluginManagement { id 'io.github.goooler.shadow' version '8.1.7' id 'de.undercouch.download' version '5.6.0' // https://projects.neoforged.net/neoforged/ModDevGradle - id 'net.neoforged.moddev' version '1.0.3' - id 'net.neoforged.moddev.repositories' version '1.0.3' + id 'net.neoforged.moddev' version '2.0.78' + id 'net.neoforged.moddev.repositories' version '2.0.78' id 'net.neoforged.gradleutils' version '3.0.0' } } @@ -19,9 +19,21 @@ plugins { dependencyResolutionManagement { repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS rulesMode = RulesMode.FAIL_ON_PROJECT_RULES + repositories { mavenCentral() } + + repositories { + maven { + name 'Maven for PR #2039' // https://github.com/neoforged/NeoForge/pull/2039 + url 'https://prmaven.neoforged.net/NeoForge/pr2039' + content { + includeModule('net.neoforged', 'neoforge') + includeModule('net.neoforged', 'testframework') + } + } + } } rootProject.name = 'serverpacklocator' diff --git a/src/utilmod/java/net/forgecraft/serverpackutility/mixin/client/MinecraftMixin.java b/src/utilmod/java/net/forgecraft/serverpackutility/mixin/client/MinecraftMixin.java index 9965974..f958b95 100644 --- a/src/utilmod/java/net/forgecraft/serverpackutility/mixin/client/MinecraftMixin.java +++ b/src/utilmod/java/net/forgecraft/serverpackutility/mixin/client/MinecraftMixin.java @@ -1,48 +1,40 @@ package net.forgecraft.serverpackutility.mixin.client; +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.realmsclient.client.RealmsClient; import net.forgecraft.serverpacklocator.ModAccessor; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.ConnectScreen; -import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; -import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.main.GameConfig; import net.minecraft.client.multiplayer.resolver.ServerAddress; import org.jetbrains.annotations.Nullable; 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; +import org.spongepowered.asm.mixin.Unique; @Mixin(Minecraft.class) public abstract class MinecraftMixin { - @Inject( - method = "lambda$buildInitialScreens$9", - at = @At("HEAD"), - cancellable = true - ) - private void inject(@Nullable Minecraft.GameLoadCookie cookie, CallbackInfo ci) { - // quit out if user requested quick play via vanilla client (launch args) - if (cookie != null && cookie.quickPlayData().isEnabled()) - return; + @Unique + private Minecraft serverpacklocator$getCurrentInstance() { + return (Minecraft) (Object) this; + } + + @WrapMethod(method = "buildInitialScreens") + private Runnable serverpacklocator$buildInitialScreens(@Nullable Minecraft.GameLoadCookie cookie, Operation operation) { // parse server address var serverAddress = ServerAddress.parseString(ModAccessor.getQuickPlayServer()); - // quit out if invalid server address passed - if (serverAddress.getHost().equals("server.invalid")) - return; - - // connect to server - ConnectScreen.startConnecting( - new JoinMultiplayerScreen(new TitleScreen()), - (Minecraft) (Object) this, - serverAddress, - new ServerData("ServerPackLocator - QuickPlay Server", serverAddress.toString(), ServerData.Type.OTHER), - true, + if ((cookie == null || !cookie.quickPlayData().isEnabled()) && !serverAddress.getHost().equals("server.invalid")) { + RealmsClient realmsclient = RealmsClient.getOrCreate(serverpacklocator$getCurrentInstance()); + cookie = new Minecraft.GameLoadCookie(realmsclient, new GameConfig.QuickPlayData( + null, + null, + serverAddress.toString(), null - ); + )); + } - // cancel vanilla code - ci.cancel(); + return operation.call(cookie); } } From 18108de2c31606d06da67b7d3cddd71a30f8b4f9 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Mon, 31 Mar 2025 19:20:37 +0200 Subject: [PATCH 2/2] Publish 1.21.5 Add documentation for NGINX --- README.md | 28 +++++++++++++++++++ gradle.properties | 2 +- .../client/MultiThreadedDownloader.java | 5 ---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7a3f7db..7fb6548 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,34 @@ SPL opens a port to listen for HTTP connections. You can change this port in the port = 8080 ``` +#### SSL Termination +By default, the included webserver does not expose a TLS based communication channel over HTTP. +This means that any server operator wishing to expose SPLs webserver over a secure channel must set this up themselves. +Luckily this can easily be done via a reverse proxy. + +> [!WARNING] +> It is highly recommended to not expose SPLs own webserver to the public, but to apply a reverse proxy. Potentially including a Web Application Firewall, and logging of requests to trace bad-actors. + +##### NGINX +Creating a reverse proxy based on NGINX is simple and you can find an example below: +```conf +server { + listen 444 ssl; + server_name yourdomain.com; + + ssl_certificate /opt/ssl/fullchain.pem; + ssl_certificate_key /opt/ssl/privkey.pem; + + location / { + proxy_pass http://localhost:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + ### Exposing Content You also configure which directories to send to the client, and whether local changes by clients will be overwritten diff --git a/gradle.properties b/gradle.properties index a815619..509c48e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -neoforgeVersion=21.5.0-alpha.1.21.5-rc1.20250323.193003 +neoforgeVersion=21.5.6-beta neoForge.parchment.minecraftVersion=1.21 neoForge.parchment.mappingsVersion=2024.07.07 diff --git a/src/main/java/net/forgecraft/serverpacklocator/client/MultiThreadedDownloader.java b/src/main/java/net/forgecraft/serverpacklocator/client/MultiThreadedDownloader.java index 0b5cc08..9c19c75 100644 --- a/src/main/java/net/forgecraft/serverpacklocator/client/MultiThreadedDownloader.java +++ b/src/main/java/net/forgecraft/serverpacklocator/client/MultiThreadedDownloader.java @@ -141,14 +141,9 @@ public ServerManifest download() throws IOException, InterruptedException { for (var fileToDownload : filesToDownload) { var bytesDownloadedAtStartOfFile = bytesDownloaded; progressBar.setAbsolute(toDownloadProgress(bytesDownloadedAtStartOfFile)); - MutableLong lastRenderTick = new MutableLong(System.currentTimeMillis()); progressBar.label("Downloading " + fileToDownload.localFile.getName() + "..."); downloadFile(fileToDownload, (downloaded, total) -> { progressBar.setAbsolute(toDownloadProgress(bytesDownloadedAtStartOfFile + downloaded)); - if (System.currentTimeMillis() - lastRenderTick.getValue() >= 50L) { - ImmediateWindowHandler.renderTick(); - lastRenderTick.setValue(System.currentTimeMillis()); - } }); // The original estimate was based on this, and the progress bar should reflect it // even if the server sent a different size