forked from MirrorHub/authlib-injector
commit
a006e784e7
5 changed files with 80 additions and 24 deletions
|
@ -28,9 +28,12 @@ import java.io.IOException;
|
|||
import java.io.UncheckedIOException;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.Proxy.Type;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -41,6 +44,8 @@ import java.util.Optional;
|
|||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import moe.yushi.authlibinjector.httpd.DefaultURLRedirector;
|
||||
|
@ -105,6 +110,11 @@ public final class AuthlibInjector {
|
|||
*/
|
||||
public static final String PROP_PRINT_UNTRANSFORMED_CLASSES = "authlibinjector.printUntransformed";
|
||||
|
||||
/**
|
||||
* The proxy to use when accessing Mojang's APIs.
|
||||
*/
|
||||
public static final String PROP_MOJANG_PROXY = "authlibinjector.mojang.proxy";
|
||||
|
||||
/**
|
||||
* The side that authlib-injector runs on.
|
||||
* Possible values: client, server.
|
||||
|
@ -322,7 +332,7 @@ public final class AuthlibInjector {
|
|||
List<URLFilter> filters = new ArrayList<>();
|
||||
|
||||
YggdrasilClient customClient = new YggdrasilClient(new CustomYggdrasilAPIProvider(config));
|
||||
YggdrasilClient mojangClient = new YggdrasilClient(new MojangYggdrasilAPIProvider());
|
||||
YggdrasilClient mojangClient = new YggdrasilClient(new MojangYggdrasilAPIProvider(), getMojangProxy());
|
||||
|
||||
if (Boolean.TRUE.equals(config.getMeta().get("feature.legacy_skin_api"))) {
|
||||
Logging.CONFIG.info("Disabled local redirect for legacy skin API, as the remote Yggdrasil server supports it");
|
||||
|
@ -336,6 +346,35 @@ public final class AuthlibInjector {
|
|||
return filters;
|
||||
}
|
||||
|
||||
private static Proxy getMojangProxy() {
|
||||
String proxyString = System.getProperty(PROP_MOJANG_PROXY);
|
||||
if (proxyString == null) {
|
||||
return null;
|
||||
}
|
||||
Matcher matcher = Pattern.compile("^(?<protocol>[^:]+)://(?<host>[^/]+)+:(?<port>\\d+)$").matcher(proxyString);
|
||||
if (!matcher.find()) {
|
||||
Logging.LAUNCH.severe("Failed to parse proxy string: " + proxyString);
|
||||
throw new InjectorInitializationException();
|
||||
}
|
||||
|
||||
String protocol = matcher.group("protocol");
|
||||
String host = matcher.group("host");
|
||||
int port = Integer.parseInt(matcher.group("port"));
|
||||
|
||||
Proxy proxy;
|
||||
switch (protocol) {
|
||||
case "socks":
|
||||
proxy = new Proxy(Type.SOCKS, new InetSocketAddress(host, port));
|
||||
break;
|
||||
|
||||
default:
|
||||
Logging.LAUNCH.severe("Unsupported proxy protocol: " + protocol);
|
||||
throw new InjectorInitializationException();
|
||||
}
|
||||
Logging.LAUNCH.info("Mojang proxy set: " + proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private static ClassTransformer createTransformer(YggdrasilConfiguration config) {
|
||||
URLProcessor urlProcessor = new URLProcessor(createFilters(config), new DefaultURLRedirector(config));
|
||||
|
||||
|
|
|
@ -21,14 +21,6 @@ public class InjectorInitializationException extends RuntimeException {
|
|||
public InjectorInitializationException() {
|
||||
}
|
||||
|
||||
public InjectorInitializationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public InjectorInitializationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InjectorInitializationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import static java.util.Optional.empty;
|
|||
import static java.util.Optional.of;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.asString;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.getURL;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.http;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.newUncheckedIOException;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonObject;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.parseJson;
|
||||
|
@ -81,7 +81,7 @@ public class LegacySkinAPIFilter implements URLFilter {
|
|||
Logging.HTTPD.fine("Retrieving skin for " + username + " from " + url);
|
||||
byte[] data;
|
||||
try {
|
||||
data = getURL(url);
|
||||
data = http("GET", url);
|
||||
} catch (IOException e) {
|
||||
throw newUncheckedIOException("Failed to retrieve skin from " + url, e);
|
||||
}
|
||||
|
|
|
@ -23,24 +23,43 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
|
||||
public final class IOUtils {
|
||||
|
||||
public static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8";
|
||||
|
||||
public static byte[] getURL(String url) throws IOException {
|
||||
try (InputStream in = new URL(url).openStream()) {
|
||||
private static HttpURLConnection createConnection(String url, Proxy proxy) throws IOException {
|
||||
if (proxy == null) {
|
||||
return (HttpURLConnection) new URL(url).openConnection();
|
||||
} else {
|
||||
return (HttpURLConnection) new URL(url).openConnection(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] http(String method, String url) throws IOException {
|
||||
return http(method, url, null);
|
||||
}
|
||||
|
||||
public static byte[] http(String method, String url, Proxy proxy) throws IOException {
|
||||
HttpURLConnection conn = createConnection(url, proxy);
|
||||
conn.setRequestMethod(method);
|
||||
try (InputStream in = conn.getInputStream()) {
|
||||
return asBytes(in);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] postURL(String url, String contentType, byte[] payload) throws IOException {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
conn.setRequestProperty("Content-Length", String.valueOf(payload.length));
|
||||
public static byte[] http(String method, String url, byte[] payload, String contentType) throws IOException {
|
||||
return http(method, url, payload, contentType, null);
|
||||
}
|
||||
|
||||
public static byte[] http(String method, String url, byte[] payload, String contentType, Proxy proxy) throws IOException {
|
||||
HttpURLConnection conn = createConnection(url, proxy);
|
||||
conn.setRequestMethod(method);
|
||||
conn.setDoOutput(true);
|
||||
conn.setFixedLengthStreamingMode(payload.length);
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
try (OutputStream out = conn.getOutputStream()) {
|
||||
out.write(payload);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,8 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||
import static java.util.Collections.singleton;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.CONTENT_TYPE_JSON;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.asString;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.getURL;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.http;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.newUncheckedIOException;
|
||||
import static moe.yushi.authlibinjector.util.IOUtils.postURL;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonArray;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonObject;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonString;
|
||||
|
@ -31,6 +30,7 @@ import static moe.yushi.authlibinjector.util.UUIDUtils.fromUnsignedUUID;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.Proxy;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -45,17 +45,23 @@ import moe.yushi.authlibinjector.yggdrasil.GameProfile.PropertyValue;
|
|||
public class YggdrasilClient {
|
||||
|
||||
private YggdrasilAPIProvider apiProvider;
|
||||
private Proxy proxy;
|
||||
|
||||
public YggdrasilClient(YggdrasilAPIProvider apiProvider) {
|
||||
this(apiProvider, null);
|
||||
}
|
||||
|
||||
public YggdrasilClient(YggdrasilAPIProvider apiProvider, Proxy proxy) {
|
||||
this.apiProvider = apiProvider;
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
public Map<String, UUID> queryUUIDs(Set<String> names) throws UncheckedIOException {
|
||||
String responseText;
|
||||
try {
|
||||
responseText = asString(postURL(
|
||||
apiProvider.queryUUIDsByNames(), CONTENT_TYPE_JSON,
|
||||
JSONArray.toJSONString(names).getBytes(UTF_8)));
|
||||
responseText = asString(http("POST", apiProvider.queryUUIDsByNames(),
|
||||
JSONArray.toJSONString(names).getBytes(UTF_8), CONTENT_TYPE_JSON,
|
||||
proxy));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
@ -82,7 +88,7 @@ public class YggdrasilClient {
|
|||
}
|
||||
String responseText;
|
||||
try {
|
||||
responseText = asString(getURL(url));
|
||||
responseText = asString(http("GET", url, proxy));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue