clean code.

This commit is contained in:
huanghongxun
2015-10-05 21:55:30 +08:00
parent 1d252ea71c
commit b9c03d6ec3
10 changed files with 244 additions and 322 deletions

View File

@@ -27,22 +27,22 @@ import org.jackhuang.hellominecraft.launcher.settings.Settings;
*/ */
public abstract class IAuthenticator { public abstract class IAuthenticator {
public static final YggdrasilAuthenticator yggdrasilLogin; public static final YggdrasilAuthenticator YGGDRASIL_LOGIN;
public static final OfflineAuthenticator offlineLogin; public static final OfflineAuthenticator OFFLINE_LOGIN;
public static final SkinmeAuthenticator skinmeLogin; public static final SkinmeAuthenticator SKINME_LOGIN;
public static final List<IAuthenticator> logins; public static final List<IAuthenticator> LOGINS;
static { static {
String clientToken = Settings.getInstance().getClientToken(); String clientToken = Settings.getInstance().getClientToken();
logins = new ArrayList<>(); LOGINS = new ArrayList<>();
logins.add(offlineLogin = new OfflineAuthenticator(clientToken)); LOGINS.add(OFFLINE_LOGIN = new OfflineAuthenticator(clientToken));
logins.add(yggdrasilLogin = new YggdrasilAuthenticator(clientToken)); LOGINS.add(YGGDRASIL_LOGIN = new YggdrasilAuthenticator(clientToken));
logins.add(skinmeLogin = new SkinmeAuthenticator(clientToken)); LOGINS.add(SKINME_LOGIN = new SkinmeAuthenticator(clientToken));
yggdrasilLogin.onLoadSettings(Settings.getInstance().getYggdrasilConfig()); YGGDRASIL_LOGIN.onLoadSettings(Settings.getInstance().getYggdrasilConfig());
Runtime.getRuntime().addShutdownHook(new Thread(() Runtime.getRuntime().addShutdownHook(new Thread(()
-> Settings.getInstance().setYggdrasilConfig(yggdrasilLogin.onSaveSettings()) -> Settings.getInstance().setYggdrasilConfig(YGGDRASIL_LOGIN.onSaveSettings())
)); ));
} }

View File

@@ -1,5 +1,13 @@
package org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil; package org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.properties.PropertyMap; import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.properties.PropertyMap;
import java.util.UUID; import java.util.UUID;
import org.jackhuang.hellominecraft.utils.StrUtils; import org.jackhuang.hellominecraft.utils.StrUtils;
@@ -11,7 +19,7 @@ public class GameProfile {
public final PropertyMap properties = new PropertyMap(); public final PropertyMap properties = new PropertyMap();
public GameProfile(UUID id, String name) { public GameProfile(UUID id, String name) {
if ((id == null) && (StrUtils.isBlank(name))) if (id == null && StrUtils.isBlank(name))
throw new IllegalArgumentException("Name and ID cannot both be blank"); throw new IllegalArgumentException("Name and ID cannot both be blank");
this.id = id; this.id = id;
@@ -19,14 +27,14 @@ public class GameProfile {
} }
public boolean isComplete() { public boolean isComplete() {
return (id != null) && (StrUtils.isNotBlank(name)); return id != null && StrUtils.isNotBlank(name);
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) if (this == o)
return true; return true;
if ((o == null) || (getClass() != o.getClass())) if (o == null || getClass() != o.getClass())
return false; return false;
GameProfile that = (GameProfile) o; GameProfile that = (GameProfile) o;
@@ -47,4 +55,25 @@ public class GameProfile {
public String toString() { public String toString() {
return "GameProfile{" + "id=" + id + ", name=" + name + ", properties=" + properties + '}'; return "GameProfile{" + "id=" + id + ", name=" + name + ", properties=" + properties + '}';
} }
public static class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile> {
@Override
public GameProfile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject object = (JsonObject) json;
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
return new GameProfile(id, name);
}
@Override
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
if (src.id != null)
result.add("id", context.serialize(src.id));
if (src.name != null)
result.addProperty("name", src.name);
return result;
}
}
} }

View File

@@ -10,7 +10,7 @@ public class UUIDTypeAdapter extends TypeAdapter<UUID> {
@Override @Override
public void write(JsonWriter out, UUID value) public void write(JsonWriter out, UUID value)
throws IOException { throws IOException {
out.value(fromUUID(value)); out.value(fromUUID(value));
} }

View File

@@ -2,19 +2,12 @@ package org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.properties.PropertyMap; import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.properties.PropertyMap;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.Proxy; import java.net.Proxy;
import java.net.URL; import java.net.URL;
@@ -22,6 +15,7 @@ import java.net.URLEncoder;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.jackhuang.hellominecraft.C; import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.GameProfile.GameProfileSerializer;
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.Response; import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.Response;
import org.jackhuang.hellominecraft.logging.logger.Logger; import org.jackhuang.hellominecraft.logging.logger.Logger;
import org.jackhuang.hellominecraft.utils.NetUtils; import org.jackhuang.hellominecraft.utils.NetUtils;
@@ -195,25 +189,4 @@ public class YggdrasilAuthenticationService {
public String getClientToken() { public String getClientToken() {
return this.clientToken; return this.clientToken;
} }
private static class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile> {
@Override
public GameProfile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject object = (JsonObject) json;
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
return new GameProfile(id, name);
}
@Override
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
if (src.id != null)
result.add("id", context.serialize(src.id));
if (src.name != null)
result.addProperty("name", src.name);
return result;
}
}
} }

View File

@@ -19,7 +19,7 @@ import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.Authe
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.RefreshResponse; import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.RefreshResponse;
import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.User; import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.response.User;
public class YggdrasilUserAuthentication { public class YggdrasilUserAuthentication {
protected static final String STORAGE_KEY_PROFILE_NAME = "displayName"; protected static final String STORAGE_KEY_PROFILE_NAME = "displayName";
protected static final String STORAGE_KEY_PROFILE_ID = "uuid"; protected static final String STORAGE_KEY_PROFILE_ID = "uuid";
@@ -35,60 +35,58 @@ public class YggdrasilUserAuthentication {
private GameProfile selectedProfile; private GameProfile selectedProfile;
public void setUsername(String username) { public void setUsername(String username) {
if ((isLoggedIn()) && (canPlayOnline())) { if ((isLoggedIn()) && (canPlayOnline()))
throw new IllegalStateException("Cannot change username whilst logged in & online"); throw new IllegalStateException("Cannot change username whilst logged in & online");
}
this.username = username; this.username = username;
} }
public void setPassword(String password) { public void setPassword(String password) {
if ((isLoggedIn()) && (canPlayOnline()) && (StrUtils.isNotBlank(password))) { if ((isLoggedIn()) && (canPlayOnline()) && (StrUtils.isNotBlank(password)))
throw new IllegalStateException("Cannot set password whilst logged in & online"); throw new IllegalStateException("Cannot set password whilst logged in & online");
}
this.password = password; this.password = password;
} }
protected String getUsername() { protected String getUsername() {
return this.username; return this.username;
} }
protected String getPassword() { protected String getPassword() {
return this.password; return this.password;
} }
protected void setSelectedProfile(GameProfile selectedProfile) { protected void setSelectedProfile(GameProfile selectedProfile) {
this.selectedProfile = selectedProfile; this.selectedProfile = selectedProfile;
} }
public GameProfile getSelectedProfile() { public GameProfile getSelectedProfile() {
return this.selectedProfile; return this.selectedProfile;
} }
public YggdrasilAuthenticationService getAuthenticationService() { public YggdrasilAuthenticationService getAuthenticationService() {
return this.authenticationService; return this.authenticationService;
} }
public String getUserID() { public String getUserID() {
return this.userid; return this.userid;
} }
public PropertyMap getUserProperties() { public PropertyMap getUserProperties() {
if (isLoggedIn()) { if (isLoggedIn()) {
PropertyMap result = new PropertyMap(); PropertyMap result = new PropertyMap();
result.putAll(getModifiableUserProperties()); result.putAll(getModifiableUserProperties());
return result; return result;
} }
return new PropertyMap(); return new PropertyMap();
} }
protected PropertyMap getModifiableUserProperties() { protected PropertyMap getModifiableUserProperties() {
return this.userProperties; return this.userProperties;
} }
protected void setUserid(String userid) { protected void setUserid(String userid) {
this.userid = userid; this.userid = userid;
} }
private static final Logger LOGGER = new Logger("YggdrasilUserAuthentication"); private static final Logger LOGGER = new Logger("YggdrasilUserAuthentication");
@@ -101,275 +99,236 @@ public class YggdrasilUserAuthentication {
private boolean isOnline; private boolean isOnline;
public YggdrasilUserAuthentication(YggdrasilAuthenticationService authenticationService) { public YggdrasilUserAuthentication(YggdrasilAuthenticationService authenticationService) {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }
public boolean canLogIn() { public boolean canLogIn() {
return (!canPlayOnline()) && (StrUtils.isNotBlank(getUsername())) && ((StrUtils.isNotBlank(getPassword())) || (StrUtils.isNotBlank(getAuthenticatedToken()))); return (!canPlayOnline()) && (StrUtils.isNotBlank(getUsername())) && ((StrUtils.isNotBlank(getPassword())) || (StrUtils.isNotBlank(getAuthenticatedToken())));
} }
public void logIn() throws AuthenticationException { public void logIn() throws AuthenticationException {
if (StrUtils.isBlank(getUsername())) { if (StrUtils.isBlank(getUsername()))
throw new AuthenticationException(C.i18n("login.invalid_username")); throw new AuthenticationException(C.i18n("login.invalid_username"));
}
if (StrUtils.isNotBlank(getAuthenticatedToken())) { if (StrUtils.isNotBlank(getAuthenticatedToken()))
logInWithToken(); logInWithToken();
} else if (StrUtils.isNotBlank(getPassword())) { else if (StrUtils.isNotBlank(getPassword()))
logInWithPassword(); logInWithPassword();
} else { else
throw new AuthenticationException(C.i18n("login.invalid_password")); throw new AuthenticationException(C.i18n("login.invalid_password"));
}
} }
protected void logInWithPassword() throws AuthenticationException { protected void logInWithPassword() throws AuthenticationException {
if (StrUtils.isBlank(getUsername())) { if (StrUtils.isBlank(getUsername()))
throw new AuthenticationException(C.i18n("login.invalid_username")); throw new AuthenticationException(C.i18n("login.invalid_username"));
} if (StrUtils.isBlank(getPassword()))
if (StrUtils.isBlank(getPassword())) { throw new AuthenticationException(C.i18n("login.invalid_password"));
throw new AuthenticationException(C.i18n("login.invalid_password"));
}
LOGGER.info("Logging in with username & password"); LOGGER.info("Logging in with username & password");
AuthenticationRequest request = new AuthenticationRequest(this, getUsername(), getPassword()); AuthenticationRequest request = new AuthenticationRequest(this, getUsername(), getPassword());
AuthenticationResponse response = (AuthenticationResponse) getAuthenticationService().makeRequest(ROUTE_AUTHENTICATE, request, AuthenticationResponse.class); AuthenticationResponse response = (AuthenticationResponse) getAuthenticationService().makeRequest(ROUTE_AUTHENTICATE, request, AuthenticationResponse.class);
if (!response.clientToken.equals(getAuthenticationService().getClientToken())) { if (!response.clientToken.equals(getAuthenticationService().getClientToken()))
throw new AuthenticationException(C.i18n("login.changed_client_token")); throw new AuthenticationException(C.i18n("login.changed_client_token"));
}
User user = response.user; User user = response.user;
if ((user != null) && (user.getId() != null)) { setUserid(user != null && user.id != null ? user.id : getUsername());
setUserid(user.getId());
} else {
setUserid(getUsername());
}
this.isOnline = true; this.isOnline = true;
this.accessToken = response.accessToken; this.accessToken = response.accessToken;
this.profiles = response.availableProfiles; this.profiles = response.availableProfiles;
setSelectedProfile(response.selectedProfile); setSelectedProfile(response.selectedProfile);
getModifiableUserProperties().clear(); getModifiableUserProperties().clear();
updateUserProperties(user); updateUserProperties(user);
} }
protected void updateUserProperties(User user) { protected void updateUserProperties(User user) {
if (user == null) { if (user == null)
return; return;
}
if (user.getProperties() != null) { if (user.properties != null)
getModifiableUserProperties().putAll(user.getProperties()); getModifiableUserProperties().putAll(user.properties);
}
} }
protected void logInWithToken() throws AuthenticationException { protected void logInWithToken() throws AuthenticationException {
if (StrUtils.isBlank(getUserID())) { if (StrUtils.isBlank(getUserID()))
if (StrUtils.isBlank(getUsername())) { if (StrUtils.isBlank(getUsername()))
setUserid(getUsername()); setUserid(getUsername());
} else { else
throw new AuthenticationException(C.i18n("login.invalid_uuid_and_username")); throw new AuthenticationException(C.i18n("login.invalid_uuid_and_username"));
} if (StrUtils.isBlank(getAuthenticatedToken()))
} throw new AuthenticationException(C.i18n("login.invalid_access_token"));
if (StrUtils.isBlank(getAuthenticatedToken())) {
throw new AuthenticationException(C.i18n("login.invalid_access_token"));
}
LOGGER.info("Logging in with access token"); LOGGER.info("Logging in with access token");
RefreshRequest request = new RefreshRequest(this); RefreshRequest request = new RefreshRequest(this);
RefreshResponse response = (RefreshResponse) getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class); RefreshResponse response = (RefreshResponse) getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if (!response.clientToken.equals(getAuthenticationService().getClientToken())) { if (!response.clientToken.equals(getAuthenticationService().getClientToken()))
throw new AuthenticationException(C.i18n("login.changed_client_token")); throw new AuthenticationException(C.i18n("login.changed_client_token"));
}
if ((response.user != null) && (response.user.getId() != null)) { setUserid(response.user != null && response.user.id != null ? response.user.id : getUsername());
setUserid(response.user.getId());
} else {
setUserid(getUsername());
}
this.isOnline = true; this.isOnline = true;
this.accessToken = response.accessToken; this.accessToken = response.accessToken;
this.profiles = response.availableProfiles; this.profiles = response.availableProfiles;
setSelectedProfile(response.selectedProfile); setSelectedProfile(response.selectedProfile);
getModifiableUserProperties().clear(); getModifiableUserProperties().clear();
updateUserProperties(response.user); updateUserProperties(response.user);
} }
public void logOut() { public void logOut() {
this.password = null; this.password = null;
this.userid = null; this.userid = null;
setSelectedProfile(null); setSelectedProfile(null);
getModifiableUserProperties().clear(); getModifiableUserProperties().clear();
this.accessToken = null; this.accessToken = null;
this.profiles = null; this.profiles = null;
this.isOnline = false; this.isOnline = false;
} }
public GameProfile[] getAvailableProfiles() { public GameProfile[] getAvailableProfiles() {
return this.profiles; return this.profiles;
} }
public boolean isLoggedIn() { public boolean isLoggedIn() {
return StrUtils.isNotBlank(this.accessToken); return StrUtils.isNotBlank(this.accessToken);
} }
public boolean canPlayOnline() { public boolean canPlayOnline() {
return (isLoggedIn()) && (getSelectedProfile() != null) && (this.isOnline); return isLoggedIn() && getSelectedProfile() != null && this.isOnline;
} }
public void selectGameProfile(GameProfile profile) throws AuthenticationException { public void selectGameProfile(GameProfile profile) throws AuthenticationException {
if (!isLoggedIn()) { if (!isLoggedIn())
throw new AuthenticationException(C.i18n("login.profile.not_logged_in")); throw new AuthenticationException(C.i18n("login.profile.not_logged_in"));
} if (getSelectedProfile() != null)
if (getSelectedProfile() != null) { throw new AuthenticationException(C.i18n("login.profile.selected"));
throw new AuthenticationException(C.i18n("login.profile.selected")); if (profile == null || !ArrayUtils.contains(this.profiles, profile))
} throw new IllegalArgumentException("Invalid profile '" + profile + "'");
if ((profile == null) || (!ArrayUtils.contains(this.profiles, profile))) {
throw new IllegalArgumentException("Invalid profile '" + profile + "'");
}
RefreshRequest request = new RefreshRequest(this, profile); RefreshRequest request = new RefreshRequest(this, profile);
RefreshResponse response = (RefreshResponse) getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class); RefreshResponse response = (RefreshResponse) getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if (!response.clientToken.equals(getAuthenticationService().getClientToken())) { if (!response.clientToken.equals(getAuthenticationService().getClientToken()))
throw new AuthenticationException(C.i18n("login.changed_client_token")); throw new AuthenticationException(C.i18n("login.changed_client_token"));
}
this.isOnline = true; this.isOnline = true;
this.accessToken = response.accessToken; this.accessToken = response.accessToken;
setSelectedProfile(response.selectedProfile); setSelectedProfile(response.selectedProfile);
} }
public void loadFromStorage(Map<String, Object> credentials) { public void loadFromStorage(Map<String, Object> credentials) {
logOut(); logOut();
setUsername((String)credentials.get("username")); setUsername((String) credentials.get("username"));
if (credentials.containsKey("userid")) { if (credentials.containsKey("userid"))
this.userid = (String)credentials.get("userid"); this.userid = (String) credentials.get("userid");
} else { else
this.userid = this.username; this.userid = this.username;
}
if (credentials.containsKey("userProperties")) { if (credentials.containsKey("userProperties"))
try { try {
List<Map> list = (List<Map>) credentials.get("userProperties"); List<Map> list = (List<Map>) credentials.get("userProperties");
for (Map propertyMap : list) { for (Map propertyMap : list) {
String name = (String) propertyMap.get("name"); String name = (String) propertyMap.get("name");
String value = (String) propertyMap.get("value"); String value = (String) propertyMap.get("value");
String signature = (String) propertyMap.get("signature"); String signature = (String) propertyMap.get("signature");
if (signature == null) { getModifiableUserProperties().put(name, new Property(name, value, signature));
getModifiableUserProperties().put(name, new Property(name, value)); }
} else { } catch (Throwable t) {
getModifiableUserProperties().put(name, new Property(name, value, signature)); LOGGER.warn("Couldn't deserialize user properties", t);
} }
}
} catch (Throwable t) {
LOGGER.warn("Couldn't deserialize user properties", t);
}
}
if ((credentials.containsKey("displayName")) && (credentials.containsKey("uuid"))) { if ((credentials.containsKey("displayName")) && (credentials.containsKey("uuid"))) {
GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String)credentials.get("uuid")), (String)credentials.get("displayName")); GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String) credentials.get("uuid")), (String) credentials.get("displayName"));
if (credentials.containsKey("profileProperties")) { if (credentials.containsKey("profileProperties"))
try { try {
List<Map> list = (List<Map>) credentials.get("profileProperties"); List<Map<String, String>> list = (List<Map<String, String>>) credentials.get("profileProperties");
for (Map propertyMap : list) { for (Map<String, String> propertyMap : list) {
String name = (String) propertyMap.get("name"); String name = propertyMap.get("name");
String value = (String) propertyMap.get("value"); String value = propertyMap.get("value");
String signature = (String) propertyMap.get("signature"); String signature = propertyMap.get("signature");
if (signature == null) { profile.properties.put(name, new Property(name, value, signature));
profile.properties.put(name, new Property(name, value)); }
} else { } catch (Throwable t) {
profile.properties.put(name, new Property(name, value, signature)); LOGGER.warn("Couldn't deserialize profile properties", t);
} }
} setSelectedProfile(profile);
} catch (Throwable t) { }
LOGGER.warn("Couldn't deserialize profile properties", t);
}
}
setSelectedProfile(profile);
}
this.accessToken = (String)credentials.get(STORAGE_KEY_ACCESS_TOKEN); this.accessToken = (String) credentials.get(STORAGE_KEY_ACCESS_TOKEN);
} }
public Map<String, Object> saveForStorage() { public Map<String, Object> saveForStorage() {
Map result = new HashMap(); Map result = new HashMap();
if (getUsername() != null) { if (getUsername() != null)
result.put("username", getUsername()); result.put("username", getUsername());
} if (getUserID() != null)
if (getUserID() != null) { result.put("userid", getUserID());
result.put("userid", getUserID()); else if (getUsername() != null)
} else if (getUsername() != null) { result.put("username", getUsername());
result.put("username", getUsername());
}
if (!getUserProperties().isEmpty()) { if (!getUserProperties().isEmpty()) {
List properties = new ArrayList(); List properties = new ArrayList();
for (Property userProperty : getUserProperties().values()) { for (Property userProperty : getUserProperties().values()) {
Map property = new HashMap(); Map<String, String> property = new HashMap<>();
property.put("name", userProperty.getName()); property.put("name", userProperty.name);
property.put("value", userProperty.getValue()); property.put("value", userProperty.value);
property.put("signature", userProperty.getSignature()); property.put("signature", userProperty.signature);
properties.add(property); properties.add(property);
} }
result.put("userProperties", properties); result.put("userProperties", properties);
} }
GameProfile sel = getSelectedProfile(); GameProfile sel = getSelectedProfile();
if (sel != null) { if (sel != null) {
result.put("displayName", sel.name); result.put("displayName", sel.name);
result.put("uuid", sel.id); result.put("uuid", sel.id);
List properties = new ArrayList(); List properties = new ArrayList();
for (Property profileProperty : sel.properties.values()) { for (Property profileProperty : sel.properties.values()) {
Map property = new HashMap(); Map<String, String> property = new HashMap<>();
property.put("name", profileProperty.getName()); property.put("name", profileProperty.name);
property.put("value", profileProperty.getValue()); property.put("value", profileProperty.value);
property.put("signature", profileProperty.getSignature()); property.put("signature", profileProperty.signature);
properties.add(property); properties.add(property);
} }
if (!properties.isEmpty()) { if (!properties.isEmpty())
result.put("profileProperties", properties); result.put("profileProperties", properties);
} }
}
if (StrUtils.isNotBlank(getAuthenticatedToken())) { if (StrUtils.isNotBlank(getAuthenticatedToken()))
result.put("accessToken", getAuthenticatedToken()); result.put("accessToken", getAuthenticatedToken());
}
return result; return result;
} }
@Deprecated @Deprecated
public String getSessionToken() { public String getSessionToken() {
if ((isLoggedIn()) && (getSelectedProfile() != null) && (canPlayOnline())) { if (isLoggedIn() && getSelectedProfile() != null && canPlayOnline())
return String.format("token:%s:%s", new Object[]{getAuthenticatedToken(), getSelectedProfile().id}); return String.format("token:%s:%s", new Object[]{getAuthenticatedToken(), getSelectedProfile().id});
} return null;
return null;
} }
public String getAuthenticatedToken() { public String getAuthenticatedToken() {
return this.accessToken; return this.accessToken;
} }
@Override @Override
public String toString() { public String toString() {
return "YggdrasilAuthenticationService{profiles=" + Arrays.toString(this.profiles) + ", selectedProfile=" + getSelectedProfile() + ", username='" + getUsername() + '\'' + ", isLoggedIn=" + isLoggedIn() + ", canPlayOnline=" + canPlayOnline() + ", accessToken='" + this.accessToken + '\'' + ", clientToken='" + getAuthenticationService().getClientToken() + '\'' + '}'; return "YggdrasilAuthenticationService{profiles=" + Arrays.toString(this.profiles) + ", selectedProfile=" + getSelectedProfile() + ", username='" + getUsername() + '\'' + ", isLoggedIn=" + isLoggedIn() + ", canPlayOnline=" + canPlayOnline() + ", accessToken='" + this.accessToken + '\'' + ", clientToken='" + getAuthenticationService().getClientToken() + '\'' + '}';
} }
} }

View File

@@ -27,7 +27,7 @@ public class LegacyPropertyMapSerializer
for (String key : src.keySet()) { for (String key : src.keySet()) {
JsonArray values = new JsonArray(); JsonArray values = new JsonArray();
values.add(new JsonPrimitive(src.get(key).getValue())); values.add(new JsonPrimitive(src.get(key).value));
result.add(key, values); result.add(key, values);
} }

View File

@@ -9,9 +9,9 @@ import org.jackhuang.hellominecraft.utils.code.Base64;
public class Property { public class Property {
private final String name; public final String name;
private final String value; public final String value;
private final String signature; public final String signature;
public Property(String value, String name) { public Property(String value, String name) {
this(value, name, null); this(value, name, null);
@@ -23,33 +23,13 @@ public class Property {
this.signature = signature; this.signature = signature;
} }
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
public String getSignature() {
return this.signature;
}
public boolean hasSignature() {
return this.signature != null;
}
public boolean isSignatureValid(PublicKey publicKey) { public boolean isSignatureValid(PublicKey publicKey) {
try { try {
Signature signature = Signature.getInstance("SHA1withRSA"); Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(publicKey); signature.initVerify(publicKey);
signature.update(this.value.getBytes()); signature.update(this.value.getBytes());
return signature.verify(Base64.decode(this.signature.toCharArray())); return signature.verify(Base64.decode(this.signature.toCharArray()));
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace(); e.printStackTrace();
} }
return false; return false;

View File

@@ -14,57 +14,47 @@ import java.util.Map;
public class PropertyMap extends HashMap<String, Property> { public class PropertyMap extends HashMap<String, Property> {
public PropertyMap() {
}
public static class Serializer implements JsonSerializer<PropertyMap>, JsonDeserializer<PropertyMap> { public static class Serializer implements JsonSerializer<PropertyMap>, JsonDeserializer<PropertyMap> {
@Override @Override
public PropertyMap deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public PropertyMap deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
PropertyMap result = new PropertyMap(); PropertyMap result = new PropertyMap();
if ((json instanceof JsonObject)) { if ((json instanceof JsonObject)) {
JsonObject object = (JsonObject) json; JsonObject object = (JsonObject) json;
for (Map.Entry<String, JsonElement> entry : object.entrySet()) { for (Map.Entry<String, JsonElement> entry : object.entrySet())
if ((entry.getValue() instanceof JsonArray)) { if ((entry.getValue() instanceof JsonArray))
for (JsonElement element : (JsonArray) entry.getValue()) { for (JsonElement element : (JsonArray) entry.getValue())
result.put(entry.getKey(), result.put(entry.getKey(),
new Property((String) entry.getKey(), element.getAsString())); new Property((String) entry.getKey(), element.getAsString()));
} } else if ((json instanceof JsonArray))
} for (JsonElement element : (JsonArray) json)
}
} else if ((json instanceof JsonArray)) {
for (JsonElement element : (JsonArray) json) {
if ((element instanceof JsonObject)) { if ((element instanceof JsonObject)) {
JsonObject object = (JsonObject) element; JsonObject object = (JsonObject) element;
String name = object.getAsJsonPrimitive("name").getAsString(); String name = object.getAsJsonPrimitive("name").getAsString();
String value = object.getAsJsonPrimitive("value").getAsString(); String value = object.getAsJsonPrimitive("value").getAsString();
if (object.has("signature")) { if (object.has("signature"))
result.put(name, new Property(name, value, object.getAsJsonPrimitive("signature").getAsString())); result.put(name, new Property(name, value, object.getAsJsonPrimitive("signature").getAsString()));
} else { else
result.put(name, new Property(name, value)); result.put(name, new Property(name, value));
}
} }
}
}
return result; return result;
} }
@Override @Override
public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) {
JsonArray result = new JsonArray(); JsonArray result = new JsonArray();
for (Property property : src.values()) { for (Property property : src.values()) {
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
object.addProperty("name", property.getName()); object.addProperty("name", property.name);
object.addProperty("value", property.getValue()); object.addProperty("value", property.value);
if (property.hasSignature()) { if (property.signature != null)
object.addProperty("signature", property.getSignature()); object.addProperty("signature", property.signature);
}
result.add(object); result.add(object);
} }

View File

@@ -4,14 +4,6 @@ import org.jackhuang.hellominecraft.launcher.utils.auth.yggdrasil.properties.Pro
public class User { public class User {
private String id; public String id;
private PropertyMap properties; public PropertyMap properties;
public String getId() {
return this.id;
}
public PropertyMap getProperties() {
return this.properties;
}
} }

View File

@@ -279,7 +279,7 @@ public class MainPagePanel extends javax.swing.JPanel {
int index = cboLoginMode.getSelectedIndex(); int index = cboLoginMode.getSelectedIndex();
if (index < 0) return; if (index < 0) return;
IAuthenticator l = IAuthenticator.logins.get(index); IAuthenticator l = IAuthenticator.LOGINS.get(index);
if (l.isHidePasswordBox()) { if (l.isHidePasswordBox()) {
pnlPassword.setVisible(false); pnlPassword.setVisible(false);
lblUserName.setText(C.i18n("login.username")); lblUserName.setText(C.i18n("login.username"));
@@ -324,7 +324,7 @@ public class MainPagePanel extends javax.swing.JPanel {
if (preaparingAuth) return; if (preaparingAuth) return;
int index = cboLoginMode.getSelectedIndex(); int index = cboLoginMode.getSelectedIndex();
IAuthenticator l = IAuthenticator.logins.get(index); IAuthenticator l = IAuthenticator.LOGINS.get(index);
CardLayout cl = (CardLayout) pnlPassword.getLayout(); CardLayout cl = (CardLayout) pnlPassword.getLayout();
if (l.isLoggedIn()) l.logout(); if (l.isLoggedIn()) l.logout();
cl.first(pnlPassword); cl.first(pnlPassword);
@@ -335,7 +335,7 @@ public class MainPagePanel extends javax.swing.JPanel {
Settings.getInstance().setUsername(txtPlayerName.getText()); Settings.getInstance().setUsername(txtPlayerName.getText());
int index = cboLoginMode.getSelectedIndex(); int index = cboLoginMode.getSelectedIndex();
if (index < 0) return; if (index < 0) return;
IAuthenticator l = IAuthenticator.logins.get(index); IAuthenticator l = IAuthenticator.LOGINS.get(index);
if (l.isHidePasswordBox()) btnRunActionPerformed(); if (l.isHidePasswordBox()) btnRunActionPerformed();
else if (!l.isLoggedIn()) txtPassword.requestFocus(); else if (!l.isLoggedIn()) txtPassword.requestFocus();
} }
@@ -366,12 +366,12 @@ public class MainPagePanel extends javax.swing.JPanel {
} }
final int index = cboLoginMode.getSelectedIndex(); final int index = cboLoginMode.getSelectedIndex();
if (index < 0 || index >= IAuthenticator.logins.size()) { if (index < 0 || index >= IAuthenticator.LOGINS.size()) {
HMCLog.warn("There's no login method."); HMCLog.warn("There's no login method.");
MessageBox.Show(C.i18n("login.methods.no_method")); MessageBox.Show(C.i18n("login.methods.no_method"));
return; return;
} }
final IAuthenticator l = IAuthenticator.logins.get(index); final IAuthenticator l = IAuthenticator.LOGINS.get(index);
final LoginInfo li = new LoginInfo(Settings.getInstance().getUsername(), l.isLoggedIn() || l.isHidePasswordBox() ? null : new String(txtPassword.getPassword())); final LoginInfo li = new LoginInfo(Settings.getInstance().getUsername(), l.isLoggedIn() || l.isHidePasswordBox() ? null : new String(txtPassword.getPassword()));
Thread t = new Thread() { Thread t = new Thread() {
@Override @Override
@@ -399,9 +399,8 @@ public class MainPagePanel extends javax.swing.JPanel {
// <editor-fold defaultstate="collapsed" desc="Loads"> // <editor-fold defaultstate="collapsed" desc="Loads">
private void prepareAuths() { private void prepareAuths() {
preaparingAuth = true; preaparingAuth = true;
List<IAuthenticator> list = IAuthenticator.logins;
cboLoginMode.removeAllItems(); cboLoginMode.removeAllItems();
for (IAuthenticator str : list) for (IAuthenticator str : IAuthenticator.LOGINS)
try { try {
cboLoginMode.addItem(str.getName()); cboLoginMode.addItem(str.getName());
} catch (Exception ex) { } catch (Exception ex) {
@@ -506,7 +505,7 @@ public class MainPagePanel extends javax.swing.JPanel {
if (showLeft) if (showLeft)
SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.first_load"))); SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.first_load")));
if (cboLoginMode.getSelectedIndex() >= 0 && cboLoginMode.getSelectedIndex() < cboLoginMode.getItemCount()) { if (cboLoginMode.getSelectedIndex() >= 0 && cboLoginMode.getSelectedIndex() < cboLoginMode.getItemCount()) {
IAuthenticator l = IAuthenticator.logins.get(cboLoginMode.getSelectedIndex()); IAuthenticator l = IAuthenticator.LOGINS.get(cboLoginMode.getSelectedIndex());
if (!l.isHidePasswordBox() && !l.isLoggedIn()) if (!l.isHidePasswordBox() && !l.isLoggedIn())
SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.enter_password"))); SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.enter_password")));
} }