mirror of
https://github.com/yushijinhun/authlib-injector.git
synced 2024-11-15 06:11:09 +01:00
Refactor URL replacing
This commit is contained in:
parent
ffd2a94b3d
commit
15f766ab29
14 changed files with 322 additions and 269 deletions
|
@ -14,17 +14,22 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import moe.yushi.authlibinjector.httpd.DefaultURLRedirector;
|
||||
import moe.yushi.authlibinjector.httpd.LegacySkinAPIFilter;
|
||||
import moe.yushi.authlibinjector.httpd.URLFilter;
|
||||
import moe.yushi.authlibinjector.httpd.URLProcessor;
|
||||
import moe.yushi.authlibinjector.transform.AuthlibLogInterceptor;
|
||||
import moe.yushi.authlibinjector.transform.ClassTransformer;
|
||||
import moe.yushi.authlibinjector.transform.ConstantURLTransformUnit;
|
||||
import moe.yushi.authlibinjector.transform.DumpClassListener;
|
||||
import moe.yushi.authlibinjector.transform.SkinWhitelistTransformUnit;
|
||||
import moe.yushi.authlibinjector.transform.LocalYggdrasilApiTransformUnit;
|
||||
import moe.yushi.authlibinjector.transform.RemoteYggdrasilTransformUnit;
|
||||
import moe.yushi.authlibinjector.transform.YggdrasilKeyTransformUnit;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
||||
|
@ -54,11 +59,6 @@ public final class AuthlibInjector {
|
|||
*/
|
||||
public static final String PROP_PREFETCHED_DATA_OLD = "org.to2mbn.authlibinjector.config.prefetched";
|
||||
|
||||
/**
|
||||
* Whether to disable the local httpd server.
|
||||
*/
|
||||
public static final String PROP_DISABLE_HTTPD = "authlibinjector.httpd.disable";
|
||||
|
||||
/**
|
||||
* The name of loggers to have debug level turned on.
|
||||
*/
|
||||
|
@ -267,9 +267,22 @@ public final class AuthlibInjector {
|
|||
}
|
||||
}
|
||||
|
||||
private static ClassTransformer createTransformer(YggdrasilConfiguration config) {
|
||||
ClassTransformer transformer = new ClassTransformer();
|
||||
private static URLProcessor createURLProcessor(YggdrasilConfiguration config) {
|
||||
List<URLFilter> filters = new ArrayList<>();
|
||||
|
||||
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");
|
||||
} else {
|
||||
filters.add(new LegacySkinAPIFilter(config));
|
||||
}
|
||||
|
||||
return new URLProcessor(filters, new DefaultURLRedirector(config));
|
||||
}
|
||||
|
||||
private static ClassTransformer createTransformer(YggdrasilConfiguration config) {
|
||||
URLProcessor urlProcessor = createURLProcessor(config);
|
||||
|
||||
ClassTransformer transformer = new ClassTransformer();
|
||||
for (String ignore : nonTransformablePackages) {
|
||||
transformer.ignores.add(ignore);
|
||||
}
|
||||
|
@ -282,11 +295,7 @@ public final class AuthlibInjector {
|
|||
transformer.units.add(new AuthlibLogInterceptor());
|
||||
}
|
||||
|
||||
if (!"true".equals(System.getProperty(PROP_DISABLE_HTTPD))) {
|
||||
transformer.units.add(new LocalYggdrasilApiTransformUnit(config));
|
||||
}
|
||||
|
||||
transformer.units.add(new RemoteYggdrasilTransformUnit(config.getApiRoot()));
|
||||
transformer.units.add(new ConstantURLTransformUnit(urlProcessor));
|
||||
|
||||
transformer.units.add(new SkinWhitelistTransformUnit(config.getSkinDomains().toArray(new String[0])));
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import moe.yushi.authlibinjector.YggdrasilConfiguration;
|
||||
|
||||
public class DefaultURLRedirector implements URLRedirector {
|
||||
|
||||
private Map<String, String> domainMapping = new HashMap<>();
|
||||
private String apiRoot;
|
||||
|
||||
public DefaultURLRedirector(YggdrasilConfiguration config) {
|
||||
initDomainMapping();
|
||||
|
||||
apiRoot = config.getApiRoot();
|
||||
}
|
||||
|
||||
private void initDomainMapping() {
|
||||
domainMapping.put("api.mojang.com", "api");
|
||||
domainMapping.put("authserver.mojang.com", "authserver");
|
||||
domainMapping.put("sessionserver.mojang.com", "sessionserver");
|
||||
domainMapping.put("skins.minecraft.net", "skins");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> redirect(String domain, String path) {
|
||||
String subdirectory = domainMapping.get(domain);
|
||||
if (subdirectory == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(apiRoot + subdirectory + path);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.singleton;
|
||||
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.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.newUncheckedIOException;
|
||||
|
@ -13,6 +15,7 @@ import static moe.yushi.authlibinjector.util.JsonUtils.asJsonArray;
|
|||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonObject;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.asJsonString;
|
||||
import static moe.yushi.authlibinjector.util.JsonUtils.parseJson;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
@ -21,7 +24,9 @@ import java.util.Optional;
|
|||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
|
||||
import fi.iki.elonen.NanoHTTPD.IHTTPSession;
|
||||
import fi.iki.elonen.NanoHTTPD.Response;
|
||||
import fi.iki.elonen.NanoHTTPD.Response.Status;
|
||||
import moe.yushi.authlibinjector.YggdrasilConfiguration;
|
||||
import moe.yushi.authlibinjector.internal.org.json.simple.JSONArray;
|
||||
|
@ -29,28 +34,28 @@ import moe.yushi.authlibinjector.internal.org.json.simple.JSONObject;
|
|||
import moe.yushi.authlibinjector.util.JsonUtils;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
||||
public class LocalYggdrasilHttpd extends NanoHTTPD {
|
||||
public class LegacySkinAPIFilter implements URLFilter {
|
||||
|
||||
public static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8";
|
||||
|
||||
private static final Pattern URL_SKINS = Pattern.compile("^/skins/MinecraftSkins/(?<username>[^/]+)\\.png$");
|
||||
private static final Pattern PATH_SKINS = Pattern.compile("^/MinecraftSkins/(?<username>[^/]+)\\.png$");
|
||||
|
||||
private YggdrasilConfiguration configuration;
|
||||
|
||||
public LocalYggdrasilHttpd(int port, YggdrasilConfiguration configuration) {
|
||||
super("127.0.0.1", port);
|
||||
public LegacySkinAPIFilter(YggdrasilConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response serve(IHTTPSession session) {
|
||||
return processAsSkin(session)
|
||||
.orElseGet(() -> super.serve(session));
|
||||
public boolean canHandle(String domain, String path) {
|
||||
return domain.equals("skins.minecraft.net");
|
||||
}
|
||||
|
||||
private Optional<Response> processAsSkin(IHTTPSession session) {
|
||||
Matcher matcher = URL_SKINS.matcher(session.getUri());
|
||||
if (!matcher.find()) return empty();
|
||||
@Override
|
||||
public Optional<Response> handle(String domain, String path, IHTTPSession session) {
|
||||
if (!domain.equals("skins.minecraft.net"))
|
||||
return empty();
|
||||
Matcher matcher = PATH_SKINS.matcher(path);
|
||||
if (!matcher.find())
|
||||
return empty();
|
||||
String username = matcher.group("username");
|
||||
|
||||
Optional<String> skinUrl;
|
||||
|
@ -138,5 +143,4 @@ public class LocalYggdrasilHttpd extends NanoHTTPD {
|
|||
.map(JsonUtils::asJsonString)
|
||||
.orElseThrow(() -> newUncheckedIOException("Invalid JSON: Missing texture url")));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import java.io.IOException;
|
||||
import moe.yushi.authlibinjector.YggdrasilConfiguration;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
||||
public class LocalYggdrasilHandle {
|
||||
|
||||
private boolean started = false;
|
||||
private YggdrasilConfiguration configuration;
|
||||
private LocalYggdrasilHttpd httpd;
|
||||
|
||||
private final Object _lock = new Object();
|
||||
|
||||
public LocalYggdrasilHandle(YggdrasilConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public void ensureStarted() {
|
||||
if (started)
|
||||
return;
|
||||
synchronized (_lock) {
|
||||
if (started)
|
||||
return;
|
||||
if (configuration == null)
|
||||
throw new IllegalStateException("Configuration hasn't been set yet");
|
||||
httpd = new LocalYggdrasilHttpd(0, configuration);
|
||||
try {
|
||||
httpd.start();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Httpd failed to start");
|
||||
}
|
||||
Logging.HTTPD.info("Httpd is running on port " + getLocalApiPort());
|
||||
started = true;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLocalApiPort() {
|
||||
if (httpd == null)
|
||||
return -1;
|
||||
return httpd.getListeningPort();
|
||||
}
|
||||
|
||||
}
|
13
src/main/java/moe/yushi/authlibinjector/httpd/URLFilter.java
Normal file
13
src/main/java/moe/yushi/authlibinjector/httpd/URLFilter.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import fi.iki.elonen.NanoHTTPD.IHTTPSession;
|
||||
import fi.iki.elonen.NanoHTTPD.Response;
|
||||
|
||||
public interface URLFilter {
|
||||
|
||||
boolean canHandle(String domain, String path);
|
||||
|
||||
Optional<Response> handle(String domain, String path, IHTTPSession session);
|
||||
}
|
108
src/main/java/moe/yushi/authlibinjector/httpd/URLProcessor.java
Normal file
108
src/main/java/moe/yushi/authlibinjector/httpd/URLProcessor.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import static fi.iki.elonen.NanoHTTPD.Response.Status.INTERNAL_ERROR;
|
||||
import static fi.iki.elonen.NanoHTTPD.Response.Status.NOT_FOUND;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
||||
public class URLProcessor {
|
||||
|
||||
private static final Pattern URL_REGEX = Pattern.compile("^https?:\\/\\/(?<domain>[^\\/]+)(?<path>\\/.*)$");
|
||||
private static final Pattern LOCAL_URL_REGEX = Pattern.compile("^/(?<domain>[^\\/]+)(?<path>\\/.*)$");
|
||||
|
||||
private List<URLFilter> filters;
|
||||
private URLRedirector redirector;
|
||||
|
||||
public URLProcessor(List<URLFilter> filters, URLRedirector redirector) {
|
||||
this.filters = filters;
|
||||
this.redirector = redirector;
|
||||
}
|
||||
|
||||
public Optional<String> transformURL(String inputUrl) {
|
||||
Matcher matcher = URL_REGEX.matcher(inputUrl);
|
||||
if (!matcher.find()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String domain = matcher.group("domain");
|
||||
String path = matcher.group("path");
|
||||
|
||||
Optional<String> result = transform(domain, path);
|
||||
if (result.isPresent()) {
|
||||
Logging.TRANSFORM.fine("Transformed url [" + inputUrl + "] to [" + result.get() + "]");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Optional<String> transform(String domain, String path) {
|
||||
boolean handleLocally = false;
|
||||
for (URLFilter filter : filters) {
|
||||
if (filter.canHandle(domain, path)) {
|
||||
handleLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (handleLocally) {
|
||||
return Optional.of("http://127.0.0.1:" + getLocalApiPort() + "/" + domain + path);
|
||||
}
|
||||
|
||||
return redirector.redirect(domain, path);
|
||||
}
|
||||
|
||||
private volatile NanoHTTPD httpd;
|
||||
private final Object httpdLock = new Object();
|
||||
|
||||
private int getLocalApiPort() {
|
||||
synchronized (httpdLock) {
|
||||
if (httpd == null) {
|
||||
httpd = createHttpd();
|
||||
try {
|
||||
httpd.start();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Httpd failed to start");
|
||||
}
|
||||
Logging.HTTPD.info("Httpd is running on port " + httpd.getListeningPort());
|
||||
}
|
||||
return httpd.getListeningPort();
|
||||
}
|
||||
}
|
||||
|
||||
private NanoHTTPD createHttpd() {
|
||||
return new NanoHTTPD("127.0.0.1", 0) {
|
||||
@Override
|
||||
public Response serve(IHTTPSession session) {
|
||||
Matcher matcher = LOCAL_URL_REGEX.matcher(session.getUri());
|
||||
if (matcher.find()) {
|
||||
String domain = matcher.group("domain");
|
||||
String path = matcher.group("path");
|
||||
for (URLFilter filter : filters) {
|
||||
if (filter.canHandle(domain, path)) {
|
||||
Optional<Response> result;
|
||||
try {
|
||||
result = filter.handle(domain, path, session);
|
||||
} catch (Throwable e) {
|
||||
Logging.HTTPD.log(Level.WARNING, "An error occurred while processing request [" + session.getUri() + "]", e);
|
||||
return newFixedLengthResponse(INTERNAL_ERROR, null, null);
|
||||
}
|
||||
|
||||
if (result.isPresent()) {
|
||||
Logging.HTTPD.fine("Request to [" + session.getUri() + "] is handled by [" + filter + "]");
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logging.HTTPD.fine("No handler is found for [" + session.getUri() + "]");
|
||||
return newFixedLengthResponse(NOT_FOUND, MIME_PLAINTEXT, "Not Found");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package moe.yushi.authlibinjector.httpd;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface URLRedirector {
|
||||
Optional<String> redirect(String domain, String path);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import moe.yushi.authlibinjector.httpd.URLProcessor;
|
||||
|
||||
public class ConstantURLTransformUnit extends LdcTransformUnit {
|
||||
|
||||
private URLProcessor urlProcessor;
|
||||
|
||||
public ConstantURLTransformUnit(URLProcessor urlProcessor) {
|
||||
this.urlProcessor = urlProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> transformLdc(String input) {
|
||||
return urlProcessor.transformURL(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Constant URL Transformer";
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class DomainBasedTransformUnit extends LdcTransformUnit {
|
||||
|
||||
private static final Pattern URL_REGEX = Pattern.compile("^https?:\\/\\/(?<domain>[^\\/]+)(?<path>\\/.*)$");
|
||||
|
||||
private Map<String, String> domainMapping = new ConcurrentHashMap<>();
|
||||
|
||||
public Map<String, String> getDomainMapping() {
|
||||
return domainMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> transformLdc(String input) {
|
||||
Matcher matcher = URL_REGEX.matcher(input);
|
||||
if (!matcher.find()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String domain = matcher.group("domain");
|
||||
String subdirectory = domainMapping.get(domain);
|
||||
if (subdirectory == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String path = matcher.group("path");
|
||||
|
||||
return Optional.of(getApiRoot() + subdirectory + path);
|
||||
}
|
||||
|
||||
protected abstract String getApiRoot();
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import moe.yushi.authlibinjector.YggdrasilConfiguration;
|
||||
import moe.yushi.authlibinjector.httpd.LocalYggdrasilHandle;
|
||||
import moe.yushi.authlibinjector.util.Logging;
|
||||
|
||||
public class LocalYggdrasilApiTransformUnit extends DomainBasedTransformUnit {
|
||||
|
||||
private LocalYggdrasilHandle handle;
|
||||
|
||||
public LocalYggdrasilApiTransformUnit(YggdrasilConfiguration config) {
|
||||
handle = new LocalYggdrasilHandle(config);
|
||||
|
||||
Map<String, String> mapping = getDomainMapping();
|
||||
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");
|
||||
} else {
|
||||
mapping.put("skins.minecraft.net", "skins");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiRoot() {
|
||||
handle.ensureStarted();
|
||||
return "http://127.0.0.1:" + handle.getLocalApiPort() + "/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Local Yggdrasil API Transformer";
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package moe.yushi.authlibinjector.transform;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RemoteYggdrasilTransformUnit extends DomainBasedTransformUnit {
|
||||
|
||||
private String apiRoot;
|
||||
|
||||
public RemoteYggdrasilTransformUnit(String apiRoot) {
|
||||
this.apiRoot = apiRoot;
|
||||
|
||||
Map<String, String> mapping = getDomainMapping();
|
||||
mapping.put("api.mojang.com", "api");
|
||||
mapping.put("authserver.mojang.com", "authserver");
|
||||
mapping.put("sessionserver.mojang.com", "sessionserver");
|
||||
mapping.put("skins.minecraft.net", "skins");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiRoot() {
|
||||
return apiRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Yggdrasil API Transformer";
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ 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()) {
|
||||
return asBytes(in);
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package moe.yushi.authlibinjector.test;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import moe.yushi.authlibinjector.YggdrasilConfiguration;
|
||||
import moe.yushi.authlibinjector.httpd.DefaultURLRedirector;
|
||||
|
||||
public class DefaultURLRedirectorTest {
|
||||
|
||||
private String apiRoot = "https://yggdrasil.example.com/";
|
||||
private DefaultURLRedirector redirector = new DefaultURLRedirector(new YggdrasilConfiguration(apiRoot, emptyList(), emptyMap(), Optional.empty()));
|
||||
|
||||
private void testTransform(String domain, String path, String output) {
|
||||
assertEquals(redirector.redirect(domain, path).get(), output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplace() {
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository
|
||||
"api.mojang.com", "/profiles/",
|
||||
"https://yggdrasil.example.com/api/profiles/");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService
|
||||
"sessionserver.mojang.com", "/session/minecraft/join",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/join");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService
|
||||
"sessionserver.mojang.com", "/session/minecraft/hasJoined",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/hasJoined");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"authserver.mojang.com", "/authenticate",
|
||||
"https://yggdrasil.example.com/authserver/authenticate");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"authserver.mojang.com", "/refresh",
|
||||
"https://yggdrasil.example.com/authserver/refresh");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"authserver.mojang.com", "/validate",
|
||||
"https://yggdrasil.example.com/authserver/validate");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"authserver.mojang.com", "/invalidate",
|
||||
"https://yggdrasil.example.com/authserver/invalidate");
|
||||
|
||||
testTransform(
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"authserver.mojang.com", "/signout",
|
||||
"https://yggdrasil.example.com/authserver/signout");
|
||||
|
||||
testTransform(
|
||||
// from: [mcp940]/net.minecraft.client.entity.AbstractClientPlayer
|
||||
// issue: yushijinhun/authlib-injector#7 <https://github.com/yushijinhun/authlib-injector/issues/7>
|
||||
"skins.minecraft.net", "/MinecraftSkins/%s.png",
|
||||
"https://yggdrasil.example.com/skins/MinecraftSkins/%s.png");
|
||||
|
||||
testTransform(
|
||||
// from: [bungeecord@806a6dfacaadb7538860889f8a50612bb496a2d3]/net.md_5.bungee.connection.InitialHandler
|
||||
// url: https://github.com/SpigotMC/BungeeCord/blob/806a6dfacaadb7538860889f8a50612bb496a2d3/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java#L409
|
||||
"sessionserver.mojang.com", "/session/minecraft/hasJoined?username=",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/hasJoined?username=");
|
||||
|
||||
testTransform(
|
||||
// from: [wiki.vg]/Mojang_API/Username -> UUID at time
|
||||
// url: http://wiki.vg/Mojang_API#Username_-.3E_UUID_at_time
|
||||
// issue: yushijinhun/authlib-injector#6 <https://github.com/yushijinhun/authlib-injector/issues/6>
|
||||
"api.mojang.com", "/users/profiles/minecraft/",
|
||||
"https://yggdrasil.example.com/api/users/profiles/minecraft/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
assertEquals(redirector.redirect("example.com", "/path"), Optional.empty());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package moe.yushi.authlibinjector.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import moe.yushi.authlibinjector.transform.RemoteYggdrasilTransformUnit;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class UrlReplaceTest {
|
||||
|
||||
private static final String apiRoot = "https://yggdrasil.example.com/";
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
// @formatter:off
|
||||
return Arrays.asList(new Object[][] {
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository
|
||||
"https://api.mojang.com/profiles/",
|
||||
"https://yggdrasil.example.com/api/profiles/"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService
|
||||
"https://sessionserver.mojang.com/session/minecraft/join",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/join"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService
|
||||
"https://sessionserver.mojang.com/session/minecraft/hasJoined",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/hasJoined"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"https://authserver.mojang.com/authenticate",
|
||||
"https://yggdrasil.example.com/authserver/authenticate"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"https://authserver.mojang.com/refresh",
|
||||
"https://yggdrasil.example.com/authserver/refresh"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"https://authserver.mojang.com/validate",
|
||||
"https://yggdrasil.example.com/authserver/validate"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"https://authserver.mojang.com/invalidate",
|
||||
"https://yggdrasil.example.com/authserver/invalidate"
|
||||
},
|
||||
{
|
||||
// from: [com.mojang:authlib:1.5.24]/com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication
|
||||
"https://authserver.mojang.com/signout",
|
||||
"https://yggdrasil.example.com/authserver/signout"
|
||||
},
|
||||
{
|
||||
// from: [mcp940]/net.minecraft.client.entity.AbstractClientPlayer
|
||||
// issue: yushijinhun/authlib-injector#7 <https://github.com/yushijinhun/authlib-injector/issues/7>
|
||||
"http://skins.minecraft.net/MinecraftSkins/%s.png",
|
||||
"https://yggdrasil.example.com/skins/MinecraftSkins/%s.png"
|
||||
},
|
||||
{
|
||||
// from: [bungeecord@806a6dfacaadb7538860889f8a50612bb496a2d3]/net.md_5.bungee.connection.InitialHandler
|
||||
// url: https://github.com/SpigotMC/BungeeCord/blob/806a6dfacaadb7538860889f8a50612bb496a2d3/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java#L409
|
||||
"https://sessionserver.mojang.com/session/minecraft/hasJoined?username=",
|
||||
"https://yggdrasil.example.com/sessionserver/session/minecraft/hasJoined?username="
|
||||
},
|
||||
{
|
||||
// from: [wiki.vg]/Mojang_API/Username -> UUID at time
|
||||
// url: http://wiki.vg/Mojang_API#Username_-.3E_UUID_at_time
|
||||
// issue: yushijinhun/authlib-injector#6 <https://github.com/yushijinhun/authlib-injector/issues/6>
|
||||
"https://api.mojang.com/users/profiles/minecraft/",
|
||||
"https://yggdrasil.example.com/api/users/profiles/minecraft/"
|
||||
}
|
||||
});
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Parameter(0)
|
||||
public String input;
|
||||
|
||||
@Parameter(1)
|
||||
public String output;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
RemoteYggdrasilTransformUnit transformer = new RemoteYggdrasilTransformUnit(apiRoot);
|
||||
assertEquals(output, transformer.transformLdc(input).get());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue