优化游戏代理参数设置 (#5273)
This commit is contained in:
@@ -46,6 +46,7 @@ import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
@@ -421,6 +422,7 @@ public final class HMCLGameRepository extends DefaultGameRepository {
|
||||
.setHeight(vs.getHeight())
|
||||
.setFullscreen(vs.isFullscreen())
|
||||
.setWrapper(vs.getWrapper())
|
||||
.setProxyOption(getProxyOption())
|
||||
.setPreLaunchCommand(vs.getPreLaunchCommand())
|
||||
.setPostExitCommand(vs.getPostExitCommand())
|
||||
.setNoGeneratedJVMArgs(vs.isNoJVMArgs())
|
||||
@@ -440,17 +442,6 @@ public final class HMCLGameRepository extends DefaultGameRepository {
|
||||
builder.setQuickPlayOption(new QuickPlayOption.MultiPlayer(vs.getServerIp()));
|
||||
}
|
||||
|
||||
if (config().hasProxy()) {
|
||||
builder.setProxyType(config().getProxyType());
|
||||
builder.setProxyHost(config().getProxyHost());
|
||||
builder.setProxyPort(config().getProxyPort());
|
||||
|
||||
if (config().hasProxyAuth()) {
|
||||
builder.setProxyUser(config().getProxyUser());
|
||||
builder.setProxyPass(config().getProxyPass());
|
||||
}
|
||||
}
|
||||
|
||||
Path json = getModpackConfiguration(version);
|
||||
if (Files.exists(json)) {
|
||||
try {
|
||||
@@ -560,4 +551,39 @@ public final class HMCLGameRepository extends DefaultGameRepository {
|
||||
return minimum;
|
||||
}
|
||||
}
|
||||
|
||||
public static ProxyOption getProxyOption() {
|
||||
if (!config().hasProxy() || config().getProxyType() == null) {
|
||||
return ProxyOption.Default.INSTANCE;
|
||||
}
|
||||
|
||||
return switch (config().getProxyType()) {
|
||||
case DIRECT -> ProxyOption.Direct.INSTANCE;
|
||||
case HTTP, SOCKS -> {
|
||||
String proxyHost = config().getProxyHost();
|
||||
int proxyPort = config().getProxyPort();
|
||||
|
||||
if (StringUtils.isBlank(proxyHost) || proxyPort < 0 || proxyPort > 0xFFFF) {
|
||||
yield ProxyOption.Default.INSTANCE;
|
||||
}
|
||||
|
||||
String proxyUser = config().getProxyUser();
|
||||
String proxyPass = config().getProxyPass();
|
||||
|
||||
if (StringUtils.isBlank(proxyUser)) {
|
||||
proxyUser = null;
|
||||
proxyPass = null;
|
||||
} else if (proxyPass == null) {
|
||||
proxyPass = "";
|
||||
}
|
||||
|
||||
if (config().getProxyType() == Proxy.Type.HTTP) {
|
||||
yield new ProxyOption.Http(proxyHost, proxyPort, proxyUser, proxyPass);
|
||||
} else {
|
||||
yield new ProxyOption.Socks(proxyHost, proxyPort, proxyUser, proxyPass);
|
||||
}
|
||||
}
|
||||
default -> ProxyOption.Default.INSTANCE;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jackhuang.hmcl.java.JavaRuntime;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.Proxy;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
@@ -49,11 +48,7 @@ public class LaunchOptions implements Serializable {
|
||||
private boolean fullscreen;
|
||||
private QuickPlayOption quickPlayOption;
|
||||
private String wrapper;
|
||||
private Proxy.Type proxyType;
|
||||
private String proxyHost;
|
||||
private int proxyPort;
|
||||
private String proxyUser;
|
||||
private String proxyPass;
|
||||
private ProxyOption proxyOption;
|
||||
private boolean noGeneratedJVMArgs;
|
||||
private boolean noGeneratedOptimizingJVMArgs;
|
||||
private String preLaunchCommand;
|
||||
@@ -195,30 +190,8 @@ public class LaunchOptions implements Serializable {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public Proxy.Type getProxyType() {
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
public String getProxyHost() {
|
||||
return proxyHost;
|
||||
}
|
||||
|
||||
public int getProxyPort() {
|
||||
return proxyPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user name of the proxy, optional.
|
||||
*/
|
||||
public String getProxyUser() {
|
||||
return proxyUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* The password of the proxy, optional
|
||||
*/
|
||||
public String getProxyPass() {
|
||||
return proxyPass;
|
||||
public ProxyOption getProxyOption() {
|
||||
return proxyOption;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,28 +395,8 @@ public class LaunchOptions implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProxyType(Proxy.Type proxyType) {
|
||||
options.proxyType = proxyType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProxyHost(String proxyHost) {
|
||||
options.proxyHost = proxyHost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProxyPort(int proxyPort) {
|
||||
options.proxyPort = proxyPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProxyUser(String proxyUser) {
|
||||
options.proxyUser = proxyUser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProxyPass(String proxyPass) {
|
||||
options.proxyPass = proxyPass;
|
||||
public Builder setProxyOption(ProxyOption proxyOption) {
|
||||
options.proxyOption = proxyOption;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2026 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/// @author Glavo
|
||||
public sealed interface ProxyOption {
|
||||
final class Direct implements ProxyOption {
|
||||
public static final Direct INSTANCE = new Direct();
|
||||
|
||||
private Direct() {
|
||||
}
|
||||
}
|
||||
|
||||
final class Default implements ProxyOption {
|
||||
public static final Default INSTANCE = new Default();
|
||||
|
||||
private Default() {
|
||||
}
|
||||
}
|
||||
|
||||
record Http(@NotNull String host, int port, @Nullable String username,
|
||||
@Nullable String password) implements ProxyOption {
|
||||
public Http {
|
||||
if (StringUtils.isBlank(host)) {
|
||||
throw new IllegalArgumentException("Host cannot be blank");
|
||||
}
|
||||
if (port < 0 || port > 0xFFFF) {
|
||||
throw new IllegalArgumentException("Illegal port: " + port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
record Socks(@NotNull String host, int port, @Nullable String username,
|
||||
@Nullable String password) implements ProxyOption {
|
||||
public Socks {
|
||||
if (StringUtils.isBlank(host)) {
|
||||
throw new IllegalArgumentException("Host cannot be blank");
|
||||
}
|
||||
if (port < 0 || port > 0xFFFF) {
|
||||
throw new IllegalArgumentException("Illegal port: " + port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.platform.*;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Proxy;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -170,22 +169,36 @@ public class DefaultLauncher extends Launcher {
|
||||
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS)
|
||||
res.addDefault("-Duser.home=", options.getGameDir().toAbsolutePath().getParent().toString());
|
||||
|
||||
Proxy.Type proxyType = options.getProxyType();
|
||||
if (proxyType == null) {
|
||||
res.addDefault("-Djava.net.useSystemProxies=", "true");
|
||||
} else {
|
||||
String proxyHost = options.getProxyHost();
|
||||
int proxyPort = options.getProxyPort();
|
||||
boolean addProxyOptions = res.noneMatch(arg ->
|
||||
arg.startsWith("-Djava.net.useSystemProxies=")
|
||||
|| arg.startsWith("-Dhttp.proxy")
|
||||
|| arg.startsWith("-Dhttps.proxy")
|
||||
|| arg.startsWith("-DsocksProxy")
|
||||
|| arg.startsWith("-Djava.net.socks.")
|
||||
);
|
||||
|
||||
if (StringUtils.isNotBlank(proxyHost) && proxyPort >= 0 && proxyPort <= 0xFFFF) {
|
||||
if (proxyType == Proxy.Type.HTTP) {
|
||||
res.addDefault("-Dhttp.proxyHost=", proxyHost);
|
||||
res.addDefault("-Dhttp.proxyPort=", String.valueOf(proxyPort));
|
||||
res.addDefault("-Dhttps.proxyHost=", proxyHost);
|
||||
res.addDefault("-Dhttps.proxyPort=", String.valueOf(proxyPort));
|
||||
} else if (proxyType == Proxy.Type.SOCKS) {
|
||||
res.addDefault("-DsocksProxyHost=", proxyHost);
|
||||
res.addDefault("-DsocksProxyPort=", String.valueOf(proxyPort));
|
||||
if (addProxyOptions) {
|
||||
if (options.getProxyOption() == null || options.getProxyOption() == ProxyOption.Default.INSTANCE) {
|
||||
res.add("-Djava.net.useSystemProxies=", "true");
|
||||
} else if (options.getProxyOption() instanceof ProxyOption.Http httpProxy) {
|
||||
res.add("-Dhttp.proxyHost=" + httpProxy.host());
|
||||
res.add("-Dhttp.proxyPort=" + httpProxy.port());
|
||||
res.add("-Dhttps.proxyHost=" + httpProxy.host());
|
||||
res.add("-Dhttps.proxyPort=" + httpProxy.port());
|
||||
|
||||
if (StringUtils.isNotBlank(httpProxy.username())) {
|
||||
res.add("-Dhttp.proxyUser=" + httpProxy.username());
|
||||
res.add("-Dhttp.proxyPassword=" + Objects.requireNonNullElse(httpProxy.password(), ""));
|
||||
res.add("-Dhttps.proxyUser=" + httpProxy.username());
|
||||
res.add("-Dhttps.proxyPassword=" + Objects.requireNonNullElse(httpProxy.password(), ""));
|
||||
}
|
||||
} else if (options.getProxyOption() instanceof ProxyOption.Socks socksProxy) {
|
||||
res.add("-DsocksProxyHost=" + socksProxy.host());
|
||||
res.add("-DsocksProxyPort=" + socksProxy.port());
|
||||
|
||||
if (StringUtils.isNotBlank(socksProxy.username())) {
|
||||
res.add("-Djava.net.socks.username=" + socksProxy.username());
|
||||
res.add("-Djava.net.socks.password=" + Objects.requireNonNullElse(socksProxy.password(), ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,21 +347,17 @@ public class DefaultLauncher extends Launcher {
|
||||
if (options.isFullscreen())
|
||||
res.add("--fullscreen");
|
||||
|
||||
if (options.getProxyType() == Proxy.Type.SOCKS) {
|
||||
String proxyHost = options.getProxyHost();
|
||||
int proxyPort = options.getProxyPort();
|
||||
|
||||
if (StringUtils.isNotBlank(proxyHost) && proxyPort >= 0 && proxyPort <= 0xFFFF) {
|
||||
res.add("--proxyHost");
|
||||
res.add(proxyHost);
|
||||
res.add("--proxyPort");
|
||||
res.add(String.valueOf(proxyPort));
|
||||
if (StringUtils.isNotBlank(options.getProxyUser()) && StringUtils.isNotBlank(options.getProxyPass())) {
|
||||
res.add("--proxyUser");
|
||||
res.add(options.getProxyUser());
|
||||
res.add("--proxyPass");
|
||||
res.add(options.getProxyPass());
|
||||
}
|
||||
// https://github.com/HMCL-dev/HMCL/issues/774
|
||||
if (options.getProxyOption() instanceof ProxyOption.Socks socksProxy) {
|
||||
res.add("--proxyHost");
|
||||
res.add(socksProxy.host());
|
||||
res.add("--proxyPort");
|
||||
res.add(String.valueOf(socksProxy.port()));
|
||||
if (StringUtils.isNotBlank(socksProxy.username())) {
|
||||
res.add("--proxyUser");
|
||||
res.add(socksProxy.username());
|
||||
res.add("--proxyPass");
|
||||
res.add(Objects.requireNonNullElse(socksProxy.password(), ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user