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