Tidy up auth data handling.

This commit is contained in:
Steveice10 2021-03-30 11:23:41 -07:00
parent 6ba99d1dbe
commit bcf5232781
3 changed files with 51 additions and 42 deletions

View file

@ -152,7 +152,7 @@ public class MinecraftProtocolTest {
SessionService sessionService = new SessionService();
sessionService.setProxy(AUTH_PROXY);
MinecraftProtocol protocol = new MinecraftProtocol(SubProtocol.STATUS);
MinecraftProtocol protocol = new MinecraftProtocol();
Client client = new Client(HOST, PORT, protocol, new TcpSessionFactory(PROXY));
client.getSession().setFlag(MinecraftConstants.SESSION_SERVICE_KEY, sessionService);
client.getSession().setFlag(MinecraftConstants.SERVER_INFO_HANDLER_KEY, new ServerInfoHandler() {
@ -193,9 +193,7 @@ public class MinecraftProtocolTest {
authService.setProxy(AUTH_PROXY);
authService.login();
// Can also use "new MinecraftProtocol(USERNAME, PASSWORD)"
// if you don't need a proxy or any other customizations.
protocol = new MinecraftProtocol(authService);
protocol = new MinecraftProtocol(authService.getSelectedProfile(), authService.getAccessToken());
System.out.println("Successfully authenticated user.");
} catch(RequestException e) {
e.printStackTrace();

View file

@ -48,6 +48,13 @@ public class ClientListener extends SessionAdapter {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getSubProtocol() == SubProtocol.LOGIN) {
if(event.getPacket() instanceof EncryptionRequestPacket) {
GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY);
String accessToken = event.getSession().getFlag(MinecraftConstants.ACCESS_TOKEN_KEY);
if(profile == null || accessToken == null) {
throw new IllegalStateException("Cannot reply to EncryptionRequestPacket without profile and access token.");
}
EncryptionRequestPacket packet = event.getPacket();
SecretKey key;
try {
@ -59,9 +66,7 @@ public class ClientListener extends SessionAdapter {
}
SessionService sessionService = event.getSession().getFlag(MinecraftConstants.SESSION_SERVICE_KEY, new SessionService());
GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY);
String serverId = sessionService.getServerId(packet.getServerId(), packet.getPublicKey(), key);
String accessToken = event.getSession().getFlag(MinecraftConstants.ACCESS_TOKEN_KEY);
try {
sessionService.joinServer(profile, accessToken, serverId);
} catch(ServiceUnavailableException e) {
@ -78,12 +83,9 @@ public class ClientListener extends SessionAdapter {
event.getSession().send(new EncryptionResponsePacket(packet.getPublicKey(), key, packet.getVerifyToken()));
protocol.enableEncryption(key);
} else if(event.getPacket() instanceof LoginSuccessPacket) {
LoginSuccessPacket packet = event.getPacket();
event.getSession().setFlag(MinecraftConstants.PROFILE_KEY, packet.getProfile());
protocol.setSubProtocol(SubProtocol.GAME, true, event.getSession());
} else if(event.getPacket() instanceof LoginDisconnectPacket) {
LoginDisconnectPacket packet = event.getPacket();
event.getSession().disconnect(packet.getReason().toString());
event.getSession().disconnect(event.<LoginDisconnectPacket>getPacket().getReason().toString());
} else if(event.getPacket() instanceof LoginSetCompressionPacket) {
event.getSession().setCompressionThreshold(event.<LoginSetCompressionPacket>getPacket().getThreshold());
}
@ -125,7 +127,7 @@ public class ClientListener extends SessionAdapter {
if(this.targetSubProtocol == SubProtocol.LOGIN) {
GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY);
event.getSession().send(new LoginStartPacket(profile != null ? profile.getName() : ""));
event.getSession().send(new LoginStartPacket(profile.getName()));
} else {
event.getSession().send(new StatusQueryPacket());
}

View file

@ -168,6 +168,7 @@ import com.github.steveice10.packetlib.packet.PacketProtocol;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
import java.security.GeneralSecurityException;
@ -177,11 +178,10 @@ import java.util.UUID;
/**
* Implements the Minecraft protocol.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MinecraftProtocol extends PacketProtocol {
private SubProtocol subProtocol = SubProtocol.HANDSHAKE;
private final PacketHeader packetHeader = new DefaultPacketHeader();
private AESEncryption encryption = null;
private AESEncryption encryption;
private SubProtocol targetSubProtocol;
@ -189,13 +189,13 @@ public class MinecraftProtocol extends PacketProtocol {
* The player's identity.
*/
@Getter
private GameProfile profile = null;
private GameProfile profile;
/**
* Authentication access token.
*/
@Getter
private String accessToken = "";
private String accessToken;
/**
* Whether to add the default client and server listeners for performing initial login.
@ -204,10 +204,38 @@ public class MinecraftProtocol extends PacketProtocol {
@Setter
private boolean useDefaultListeners = true;
/**
* Constructs a new MinecraftProtocol instance for making status queries.
*/
public MinecraftProtocol() {
this.targetSubProtocol = SubProtocol.STATUS;
}
/**
* Constructs a new MinecraftProtocol instance for logging in using offline mode.
* @param username Username to use.
*/
public MinecraftProtocol(@NonNull String username) {
this(new GameProfile((UUID) null, username), null);
}
/**
* Constructs a new MinecraftProtocol instance for logging in.
* @param profile GameProfile to use.
* @param accessToken Access token to use, or null if using offline mode.
*/
public MinecraftProtocol(@NonNull GameProfile profile, String accessToken) {
this.targetSubProtocol = SubProtocol.LOGIN;
this.profile = profile;
this.accessToken = accessToken;
}
/**
* Constructs a new MinecraftProtocol instance, starting with a specific {@link SubProtocol}.
* @param subProtocol {@link SubProtocol} to start with.
* @deprecated Use the no-args constructor for status queries or the appropriate constructor for logging in.
*/
@Deprecated
public MinecraftProtocol(SubProtocol subProtocol) {
if(subProtocol != SubProtocol.LOGIN && subProtocol != SubProtocol.STATUS) {
throw new IllegalArgumentException("Only login and status modes are permitted.");
@ -219,20 +247,12 @@ public class MinecraftProtocol extends PacketProtocol {
}
}
/**
* Constructs a new MinecraftProtocol instance, adopting the given username.
* @param username Username to adopt.
*/
public MinecraftProtocol(String username) {
this(SubProtocol.LOGIN);
this.profile = new GameProfile((UUID) null, username);
}
/**
* Constructs a new MinecraftProtocol instance, logging in with the given password credentials.
* @param username Username to log in as. Must be the same as when the access token was generated.
* @param password Password to log in with.
* @throws RequestException If the log in request fails.
* @deprecated Login beforehand and use the (profile, accessToken) constructor.
*/
@Deprecated
public MinecraftProtocol(String username, String password) throws RequestException {
@ -245,6 +265,7 @@ public class MinecraftProtocol extends PacketProtocol {
* @param clientToken Client token to log in as. Must be the same as when the access token was generated.
* @param accessToken Access token to log in with.
* @throws RequestException If the log in request fails.
* @deprecated Login beforehand and use the (profile, accessToken) constructor.
*/
@Deprecated
public MinecraftProtocol(String username, String clientToken, String accessToken) throws RequestException {
@ -255,7 +276,9 @@ public class MinecraftProtocol extends PacketProtocol {
* Constructs a new MinecraftProtocol instance, copying authentication information
* from a logged-in {@link AuthenticationService}.
* @param authService {@link AuthenticationService} to copy from.
* @deprecated Use the (profile, accessToken) constructor.
*/
@Deprecated
public MinecraftProtocol(AuthenticationService authService) {
this(authService.getSelectedProfile(), authService.getAccessToken());
}
@ -265,23 +288,11 @@ public class MinecraftProtocol extends PacketProtocol {
* @param profile GameProfile to use.
* @param clientToken Client token to use.
* @param accessToken Access token to use.
* @deprecated Use the (profile, accessToken) constructor.
*/
@Deprecated
public MinecraftProtocol(GameProfile profile, String clientToken, String accessToken) {
this(SubProtocol.LOGIN);
this.profile = profile;
this.accessToken = accessToken;
}
/**
* Constructs a new MinecraftProtocol from authentication information.
* @param profile GameProfile to use.
* @param accessToken Access token to use.
*/
public MinecraftProtocol(GameProfile profile, String accessToken) {
this(SubProtocol.LOGIN);
this.profile = profile;
this.accessToken = accessToken;
this(profile, accessToken);
}
private static AuthenticationService createAuthServiceForPasswordLogin(String username, String password) throws RequestException {
@ -317,10 +328,8 @@ public class MinecraftProtocol extends PacketProtocol {
@Override
public void newClientSession(Client client, Session session) {
if(this.profile != null) {
session.setFlag(MinecraftConstants.PROFILE_KEY, this.profile);
session.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, this.accessToken);
}
session.setFlag(MinecraftConstants.PROFILE_KEY, this.profile);
session.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, this.accessToken);
this.setSubProtocol(SubProtocol.HANDSHAKE, true, session);