mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
refactor: ProxyAgnosticMojangResolver
ProxyAgnosticMojangResolver serves as a cleaner implementation of the hasJoined static method from previous commit. All the reflection involved was removed due to no longer being necessary. This way, a lot cleaner code could be made. All the inner workings remained the same. For more information on how it works, check out ProxyAgnosticMojangResolver.java.
This commit is contained in:
@ -141,10 +141,7 @@ public class VerifyResponseTask implements Runnable {
|
||||
try {
|
||||
MojangResolver resolver = plugin.getCore().getResolver();
|
||||
InetAddress address = socketAddress.getAddress();
|
||||
|
||||
// TODO edit marker
|
||||
Optional<Verification> response = VerifyResponseTask.hasJoined(resolver, requestedUsername, serverId, address);
|
||||
|
||||
Optional<Verification> response = resolver.hasJoined(requestedUsername, serverId, address);
|
||||
if (response.isPresent()) {
|
||||
Verification verification = response.get();
|
||||
plugin.getLog().info("Profile {} has a verified premium account", requestedUsername);
|
||||
@ -176,83 +173,6 @@ public class VerifyResponseTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A reimplementation of {@link MojangResolver#hasJoined(String, String, InetAddress)} using various crude reflection-based hacks
|
||||
* to access the protected code. The significant difference is that unlike in the CraftAPI implementation, which sends the "ip" parameter
|
||||
* when the hostIp parameter is an IPv4 address, but skips it for IPv6, this implementation ommits the "ip" parameter also for IPv4, effectively
|
||||
* enabling transparent proxies to work.
|
||||
*
|
||||
* TODO Reimplement as MojangResolver subclass overriding hasJoined method -> "ProxyAgnosticMojangResolver" perhaps?
|
||||
*
|
||||
* @param resolver The mojang resolver object the method will operate on
|
||||
* @param username The literal username of the player
|
||||
* @param serverHash The computed server hash sent to mojang session servers
|
||||
* @param hostIp The host IP address - not used, kept to maintain similar signature
|
||||
* @return An optional object containing the verification information, if any. If there is no verification information, the session servers consider the join invalid.
|
||||
* @throws IOException When an error occurs during the HTTP communication
|
||||
* @author games647, Enginecrafter77
|
||||
*/
|
||||
public static Optional<Verification> hasJoined(MojangResolver resolver, String username, String serverHash, InetAddress hostIp) throws IOException {
|
||||
/*String url;
|
||||
if (hostIp instanceof Inet6Address) {
|
||||
url = String.format("https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s", username, serverHash);
|
||||
} else {
|
||||
String encodedIP = URLEncoder.encode(hostIp.getHostAddress(), StandardCharsets.UTF_8.name());
|
||||
url = String.format("https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s&ip=%s", username, serverHash, encodedIP);
|
||||
}*/
|
||||
String url = String.format("https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s", username, serverHash);
|
||||
|
||||
try
|
||||
{
|
||||
Class<?> inputStreamActionClass = Class.forName("com.github.games647.craftapi.resolver.AbstractResolver$InputStreamAction");
|
||||
Method getConnectionMethod = AbstractResolver.class.getDeclaredMethod("getConnection", String.class);
|
||||
Method parseRequestMethod = AbstractResolver.class.getDeclaredMethod("parseRequest", HttpURLConnection.class, inputStreamActionClass);
|
||||
Method readJsonMethod = AbstractResolver.class.getDeclaredMethod("readJson", InputStream.class, Class.class);
|
||||
|
||||
getConnectionMethod.setAccessible(true);
|
||||
parseRequestMethod.setAccessible(true);
|
||||
readJsonMethod.setAccessible(true);
|
||||
|
||||
HttpURLConnection conn = (HttpURLConnection)getConnectionMethod.invoke(resolver, url);
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
Verification result = null;
|
||||
if(responseCode != 204)
|
||||
{
|
||||
AbstractResolverAdapter.InputStreamActionAdapter<Verification> action = new AbstractResolverAdapter.InputStreamActionAdapter<Verification>() {
|
||||
@Override
|
||||
public Verification useStream(InputStream inp) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Verification)readJsonMethod.invoke(resolver, new Object[] {inp, Verification.class});
|
||||
}
|
||||
catch(ReflectiveOperationException exc)
|
||||
{
|
||||
throw new IOException("Reflective method access failed", exc);
|
||||
}
|
||||
}
|
||||
};
|
||||
result = (Verification)parseRequestMethod.invoke(resolver, new Object[] {conn, action});
|
||||
}
|
||||
return Optional.ofNullable(result);
|
||||
}
|
||||
catch(ReflectiveOperationException exc)
|
||||
{
|
||||
throw new RuntimeException("Error occured in reflective hacks to MojangResolver", exc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An adapter class used to make the InputStreamAction interface accessible to us.
|
||||
* I know, it's a crude and disgusting solution, but bear with me, it's just temporary.
|
||||
*/
|
||||
public static class AbstractResolverAdapter extends AbstractResolver
|
||||
{
|
||||
@FunctionalInterface
|
||||
protected static interface InputStreamActionAdapter<R> extends AbstractResolver.InputStreamAction<R> {}
|
||||
}
|
||||
|
||||
private void setPremiumUUID(UUID premiumUUID) {
|
||||
if (plugin.getConfig().getBoolean("premiumUuid") && premiumUUID != null) {
|
||||
try {
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2022 games647 and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.github.games647.fastlogin.core.mojang;
|
||||
|
||||
import com.github.games647.craftapi.model.auth.Verification;
|
||||
import com.github.games647.craftapi.resolver.MojangResolver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* An extension to {@link MojangResolver} which allows connection using transparent reverse proxies.
|
||||
* The significant difference is that unlike MojangResolver from the CraftAPI implementation, which sends the "ip" parameter
|
||||
* when the hostIp parameter is an IPv4 address, but skips it for IPv6, this implementation leaves out the "ip" parameter
|
||||
* also for IPv4, effectively enabling transparent proxies to work.
|
||||
* @author games647, Enginecrafter77
|
||||
*/
|
||||
public class ProxyAgnosticMojangResolver extends MojangResolver {
|
||||
@Override
|
||||
public Optional<Verification> hasJoined(String username, String serverHash, InetAddress hostIp) throws IOException
|
||||
{
|
||||
String url = String.format("https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s", username, serverHash);
|
||||
|
||||
HttpURLConnection conn = this.getConnection(url);
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
Verification verification = null;
|
||||
if(responseCode != 204)
|
||||
verification = this.parseRequest(conn, this::parseVerification);
|
||||
return Optional.ofNullable(verification);
|
||||
}
|
||||
|
||||
// Functional implementation of InputStreamAction
|
||||
protected Verification parseVerification(InputStream input) throws IOException
|
||||
{
|
||||
return this.readJson(input, Verification.class);
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ import com.github.games647.fastlogin.core.TickingRateLimiter;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
|
||||
import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
|
||||
import com.github.games647.fastlogin.core.mojang.ProxyAgnosticMojangResolver;
|
||||
import com.github.games647.fastlogin.core.storage.MySQLStorage;
|
||||
import com.github.games647.fastlogin.core.storage.SQLStorage;
|
||||
import com.github.games647.fastlogin.core.storage.SQLiteStorage;
|
||||
@ -83,7 +84,8 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
private final Collection<UUID> pendingConfirms = new HashSet<>();
|
||||
private final T plugin;
|
||||
|
||||
private final MojangResolver resolver = new MojangResolver();
|
||||
//private final MojangResolver resolver = new MojangResolver();
|
||||
private final MojangResolver resolver = new ProxyAgnosticMojangResolver();
|
||||
|
||||
private Configuration config;
|
||||
private SQLStorage storage;
|
||||
|
Reference in New Issue
Block a user