/* * SK's Minecraft Launcher * Copyright (C) 2010, 2011 Albert Pham <http://www.sk89q.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.timvisee.minecraftrunner; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import javax.net.ssl.HttpsURLConnection; /** * Manages a login session. * * @author sk89q */ public class LoginSession { // Constants private static final String MINECRAFT_LOGIN_URL = "https://login.minecraft.net/"; private static final String LAUNCHER_VERSION = "13"; private String user; private URL loginURL; private boolean isValid; private String latestVer; private String downloadTicket; private String sessId; /** * Construct the session. * * @param username username */ public LoginSession(String username) { // Store the username this.user = username; // Define the login URL try { this.loginURL = new URL(MINECRAFT_LOGIN_URL); } catch (MalformedURLException e) { throw new RuntimeException(e); } } /** * Attempt to login. * * @param password plain text password * @return true if successful * @throws IOException throw on an IO error * @throws OutdatedLauncherException thrown on an outdated launcher exception * @throws LoginException thrown on an unknown login exception */ public boolean login(String password) throws IOException, OutdatedLauncherException, LoginException { // Define the connection variable HttpsURLConnection conn = null; // HTTP request URL params String params = String.format("user=%s&password=%s&version=%s", URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(password, "UTF-8"), URLEncoder.encode(LAUNCHER_VERSION, "UTF-8")); try { // Open the connection conn = (HttpsURLConnection) loginURL.openConnection(); // Set the connection stuff conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length)); conn.setRequestProperty("Content-Language", "en-US"); conn.setReadTimeout(1000 * 60 * 10); // Connect conn.connect(); // Get the output data DataOutputStream out = new DataOutputStream(conn.getOutputStream()); out.writeBytes(params); out.flush(); out.close(); if (conn.getResponseCode() != 200) throw new IOException("Did not get expected 200 code"); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); StringBuilder s = new StringBuilder(); char[] buf = new char[1024]; int len = 0; while ((len = reader.read(buf)) != -1) { s.append(buf, 0, len); } String result = s.toString(); if (result.contains(":")) { String[] values = result.split(":"); try { latestVer = values[0].trim(); downloadTicket = values[1].trim(); user = values[2].trim(); sessId = values[3].trim(); } catch (ArrayIndexOutOfBoundsException e) { throw new LoginException("Returned login payload had an incorrect number of arguments"); } isValid = true; return true; } else { if (result.trim().equals("Bad login")) { return false; } else if (result.trim().equals("Old version")) { throw new OutdatedLauncherException(); } else { throw new LoginException(result.trim()); } } } finally { if (conn != null) conn.disconnect(); conn = null; } } /** * Returns whether the session has been authenticated. * * @return true is authenticated */ public boolean isValid() { return isValid; } /** * Get the username. If a login was successful, this will be the correct * form of the username. * * @return username */ public String getUsername() { return user; } /** * Get the latest version of Minecraft, available once logged in. * * @return version string */ public String getLatestVersion() { return latestVer; } /** * Get the download ticket, available once logged in. * * @return download ticket */ public String getDownloadTicket() { return downloadTicket; } /** * Get the session ID, available once logged in. * * @return session ID */ public String getSessionId() { return sessId; } /** * Get the login URL being used. * * @return url */ public URL getLoginURL() { return loginURL; } public static class LoginException extends Exception { private static final long serialVersionUID = 3704469434921739106L; public LoginException(String message) { super(message); } public LoginException(String message, Throwable t) { super(message, t); } } public static class OutdatedLauncherException extends Exception { private static final long serialVersionUID = -7109390633647649010L; } }