package net.minecraft.launcher.authentication;
import net.minecraft.launcher.Launcher;
import net.minecraft.launcher.authentication.exceptions.AuthenticationException;
import net.minecraft.launcher.authentication.exceptions.InvalidCredentialsException;
import net.minecraft.launcher.events.AuthenticationChangedListener;
import org.apache.commons.lang3.StringUtils;
import org.hopto.energy.HashUtil;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.swing.*;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
/**
* Created by Energy on 13年7月2日.
*/
public class SPAuthenticationService implements AuthenticationService {
private static final String LEGACY_LASTLOGIN_PASSWORD = "passwordfile";
private static final int LEGACY_LASTLOGIN_SEED = 43287234;
private final List<AuthenticationChangedListener> listeners = new ArrayList();
private String sessionToken = "";
private String username = "";
private String password = "";
private String uuid = "";
private GameProfile selectedProfile = null;
private boolean shouldRememberMe = true;
public static String[] getStoredDetails(File lastLoginFile) {
if (!lastLoginFile.isFile()) return null;
try {
Cipher cipher = getCipher(2, "passwordfile");
DataInputStream dis;
if (cipher != null)
dis = new DataInputStream(new CipherInputStream(new FileInputStream(lastLoginFile), cipher));
else {
dis = new DataInputStream(new FileInputStream(lastLoginFile));
}
String username = dis.readUTF();
String password = dis.readUTF();
dis.close();
return new String[]{username, password};
} catch (Exception e) {
Launcher.getInstance().println("Couldn't load old lastlogin file", e);
}
return null;
}
private static Cipher getCipher(int mode, String password) throws Exception {
Random random = new Random(43287234L);
byte[] salt = new byte[8];
random.nextBytes(salt);
PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 5);
SecretKey pbeKey = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec(password.toCharArray()));
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(mode, pbeKey, pbeParamSpec);
return cipher;
}
@Override
public boolean canLogIn() {
return !canPlayOnline();
}
@Override
public void logIn() throws AuthenticationException {
Map args = new HashMap();
args.put("user", getUsername());
args.put("password", getPassword());
args.put("version", Integer.valueOf(14));
uuid = HashUtil.getMD5(getUsername());
String response = "0:0:" + getUsername() + ":0:" + uuid;
/*try { response = Http.performPost(AUTHENTICATION_URL, args, Launcher.getInstance().getProxy()).trim();
} catch (IOException e) {
throw new AuthenticationException("Authentication server is not responding", e);
}*/
String[] split = response.split(":");
if (split.length == 5) {
// String profileId = Long.toString(System.currentTimeMillis());
String profileId = split[4];
String profileName = split[2];
String sessionToken = split[3];
if ((StringUtils.isBlank(profileId)) || (StringUtils.isBlank(profileName)) || (StringUtils.isBlank(sessionToken))) {
throw new AuthenticationException("Unknown response from authentication server: " + response);
}
setSelectedProfile(new GameProfile(profileId, profileName));
this.sessionToken = sessionToken;
fireAuthenticationChangedEvent();
} else {
throw new InvalidCredentialsException(response);
}
}
@Override
public void logOut() {
this.password = null;
setSelectedProfile(null);
this.sessionToken = null;
fireAuthenticationChangedEvent();
}
@Override
public boolean isLoggedIn() {
return getSelectedProfile() != null;
}
@Override
public boolean canPlayOnline() {
return (isLoggedIn()) && (getSelectedProfile() != null) && (getSessionToken() != null);
}
@Override
public GameProfile[] getAvailableProfiles() {
if (getSelectedProfile() != null) {
return new GameProfile[]{getSelectedProfile()};
}
return new GameProfile[0];
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public GameProfile getSelectedProfile() {
return this.selectedProfile;
}
public void setSelectedProfile(GameProfile selectedProfile) {
this.selectedProfile = selectedProfile;
}
@Override
public void selectGameProfile(GameProfile paramGameProfile) throws AuthenticationException {
}
@Override
public void loadFromStorage(Map<String, String> credentials) {
logOut();
if (credentials.containsKey("rememberMe")) {
setRememberMe(Boolean.getBoolean((String) credentials.get("rememberMe")));
}
setUsername((String) credentials.get("username"));
if ((credentials.containsKey("displayName")) && (credentials.containsKey("uuid")))
setSelectedProfile(new GameProfile((String) credentials.get("uuid"), (String) credentials.get("displayName")));
}
public Map<String, String> saveForStorage() {
Map result = new HashMap();
if (!shouldRememberMe()) {
result.put("rememberMe", Boolean.toString(false));
return result;
}
if (getUsername() != null) {
result.put("username", getUsername());
}
if (getSelectedProfile() != null) {
result.put("displayName", getSelectedProfile().getName());
result.put("uuid", getSelectedProfile().getId());
}
return result;
}
public boolean shouldRememberMe() {
return this.shouldRememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.shouldRememberMe = rememberMe;
}
@Override
public String getSessionToken() {
return this.sessionToken;
}
public void setSessionToken(String sessionToken) {
this.sessionToken = sessionToken;
}
public String getAccessToken() {
return "-";
}
@Override
public String getUsername() {
return this.username;
}
@Override
public void setUsername(String username) {
this.username = username;
}
protected String getPassword() {
return this.password;
}
@Override
public void setPassword(String password) {
this.password = password;
}
public void addAuthenticationChangedListener(AuthenticationChangedListener listener) {
this.listeners.add(listener);
}
public void removeAuthenticationChangedListener(AuthenticationChangedListener listener) {
this.listeners.remove(listener);
}
@Override
public String guessPasswordFromSillyOldFormat(File file) {
String[] details = getStoredDetails(file);
if ((details != null) &&
(details[0].equals(getUsername()))) {
return details[1];
}
return null;
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append(getClass().getSimpleName());
result.append("{");
if (isLoggedIn()) {
result.append("Logged in as ");
result.append(getUsername());
if (getSelectedProfile() != null) {
result.append(" / ");
result.append(getSelectedProfile());
result.append(" - ");
if (canPlayOnline()) {
result.append("Online with session token '");
result.append(getSessionToken());
result.append("'");
} else {
result.append("Offline");
}
}
} else {
result.append("Not logged in");
}
result.append("}");
return result.toString();
}
protected void fireAuthenticationChangedEvent() {
final List listeners = new ArrayList(this.listeners);
for (Iterator iterator = listeners.iterator(); iterator.hasNext(); ) {
AuthenticationChangedListener listener = (AuthenticationChangedListener) iterator.next();
if (!listener.shouldReceiveEventsInUIThread()) {
listener.onAuthenticationChanged(this);
iterator.remove();
}
}
if (!listeners.isEmpty())
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for (AuthenticationChangedListener listener : (ArrayList<AuthenticationChangedListener>) listeners)
listener.onAuthenticationChanged(SPAuthenticationService.this);
}
});
}
}