Commit fca9591f3e44497d96960ffb69ecf838bc8216af
1 parent
1ffb7333
LiteLoader 1.6.4_02 - dev only - replace launcher jar with authlib, add better s…
…upport for yggdrasil token auth with login dialog box
Showing
15 changed files
with
630 additions
and
129 deletions
.classpath
| ... | ... | @@ -7,15 +7,14 @@ |
| 7 | 7 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
| 8 | 8 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar"/> |
| 9 | 9 | <classpathentry kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar"/> |
| 10 | - <classpathentry kind="lib" path="/Client/jars/libraries/com/google/guava/guava/14.0/guava-14.0.jar"> | |
| 11 | - <attributes> | |
| 12 | - <attribute name="javadoc_location" value="jar:platform:/resource/LiteLoader/javadoc/guava-14.0.1-javadoc.jar!/"/> | |
| 13 | - </attributes> | |
| 14 | - </classpathentry> | |
| 10 | + <classpathentry kind="lib" path="/Client/jars/libraries/com/google/guava/guava/14.0/guava-14.0.jar"/> | |
| 15 | 11 | <classpathentry kind="lib" path="/Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar"/> |
| 16 | 12 | <classpathentry exported="true" kind="lib" path="lib/launchwrapper-1.8.jar"/> |
| 17 | - <classpathentry kind="lib" path="lib/jopt-simple-4.5.jar"/> | |
| 18 | - <classpathentry kind="lib" path="lib/launcher.jar"/> | |
| 19 | 13 | <classpathentry exported="true" kind="lib" path="lib/asm-debug-all-4.1.jar"/> |
| 14 | + <classpathentry kind="lib" path="lib/authlib-1.3.jar" sourcepath="/AuthLib/java"/> | |
| 15 | + <classpathentry kind="lib" path="/Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar"/> | |
| 16 | + <classpathentry kind="lib" path="lib/log4j-api-2.0-beta9.jar"/> | |
| 17 | + <classpathentry kind="lib" path="lib/log4j-core-2.0-beta9.jar"/> | |
| 18 | + <classpathentry kind="lib" path="/Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"/> | |
| 20 | 19 | <classpathentry kind="output" path="bin"/> |
| 21 | 20 | </classpath> | ... | ... |
ant/build_liteloader.xml
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" ?> |
| 2 | 2 | <project name="liteloader" basedir="." default="rebuild"> |
| 3 | 3 | |
| 4 | - <taskdef resource="net/sf/antcontrib/antcontrib.properties"/> | |
| 4 | + <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="tasks/ant-contrib.jar" /> | |
| 5 | 5 | |
| 6 | 6 | <!-- Versions !!IMPORTANT --> |
| 7 | 7 | <property name="version" value="1.6.4" /> |
| ... | ... | @@ -130,16 +130,20 @@ |
| 130 | 130 | <target name="prepare" description="Prepare source for MCP" depends="preparemd5"> |
| 131 | 131 | <echo level="info" message="Prepare sources for compile" /> |
| 132 | 132 | |
| 133 | + <echo level="info" message="Contributing libs" /> | |
| 133 | 134 | <copy todir="${libs}" verbose="true" overwrite="true"> |
| 134 | 135 | <fileset dir="${eclipse}/LiteLoader/lib"> |
| 135 | - <exclude name="**/launcher.jar" /> | |
| 136 | + <exclude name="**/authlib*.jar" /> | |
| 137 | + <exclude name="**/log4j*.jar" /> | |
| 136 | 138 | </fileset> |
| 137 | 139 | </copy> |
| 138 | 140 | |
| 141 | + <echo level="info" message="Contributing MC source" /> | |
| 139 | 142 | <copy todir="${src}" verbose="false" overwrite="true"> |
| 140 | 143 | <fileset dir="${mc.src}" /> |
| 141 | 144 | </copy> |
| 142 | 145 | |
| 146 | + <echo level="info" message="Contributing upstream projects" /> | |
| 143 | 147 | <foreach list="${upstream}" param="lib" target="contributesource" /> |
| 144 | 148 | |
| 145 | 149 | <antcall target="contributesource"> | ... | ... |
ant/ant-contrib.jar renamed to ant/tasks/ant-contrib.jar
No preview for this file type
debug/com/mumfrey/liteloader/debug/AuthenticationRequest.java deleted
100644 → 0
| 1 | -package com.mumfrey.liteloader.debug; | |
| 2 | - | |
| 3 | -import java.util.UUID; | |
| 4 | - | |
| 5 | -import net.minecraft.launcher.authentication.yggdrasil.Agent; | |
| 6 | - | |
| 7 | -@SuppressWarnings("unused") | |
| 8 | -public class AuthenticationRequest | |
| 9 | -{ | |
| 10 | - private Agent agent; | |
| 11 | - private String username; | |
| 12 | - private String password; | |
| 13 | - private String clientToken; | |
| 14 | - | |
| 15 | - public AuthenticationRequest(String username, String password) | |
| 16 | - { | |
| 17 | - this.agent = Agent.MINECRAFT; | |
| 18 | - this.username = username; | |
| 19 | - this.password = password; | |
| 20 | - this.clientToken = UUID.randomUUID().toString(); | |
| 21 | - } | |
| 22 | -} | |
| 23 | - |
debug/com/mumfrey/liteloader/debug/LoginManager.java
0 → 100644
| 1 | +package com.mumfrey.liteloader.debug; | |
| 2 | + | |
| 3 | +import java.io.File; | |
| 4 | +import java.io.FileReader; | |
| 5 | +import java.io.FileWriter; | |
| 6 | +import java.io.IOException; | |
| 7 | +import java.net.Proxy; | |
| 8 | +import java.util.Map; | |
| 9 | +import java.util.UUID; | |
| 10 | +import java.util.logging.Logger; | |
| 11 | + | |
| 12 | +import com.google.common.base.Strings; | |
| 13 | +import com.google.gson.Gson; | |
| 14 | +import com.google.gson.GsonBuilder; | |
| 15 | +import com.google.gson.JsonIOException; | |
| 16 | +import com.google.gson.JsonSyntaxException; | |
| 17 | +import com.mojang.authlib.Agent; | |
| 18 | +import com.mojang.authlib.GameProfile; | |
| 19 | +import com.mojang.authlib.exceptions.AuthenticationException; | |
| 20 | +import com.mojang.authlib.exceptions.InvalidCredentialsException; | |
| 21 | +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; | |
| 22 | +import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * Manages login requests against Yggdrasil for use in MCP | |
| 26 | + * | |
| 27 | + * @author Adam Mummery-Smith | |
| 28 | + */ | |
| 29 | +public class LoginManager | |
| 30 | +{ | |
| 31 | + private static Logger logger = Logger.getLogger("liteloader"); | |
| 32 | + | |
| 33 | + private static Gson gson = new GsonBuilder().setPrettyPrinting().create(); | |
| 34 | + | |
| 35 | + private YggdrasilAuthenticationService authService; | |
| 36 | + | |
| 37 | + private YggdrasilUserAuthentication authentication; | |
| 38 | + | |
| 39 | + private File jsonFile; | |
| 40 | + | |
| 41 | + private String defaultUsername; | |
| 42 | + | |
| 43 | + private String defaultDisplayName = System.getProperty("user.name"); | |
| 44 | + | |
| 45 | + private boolean offline = false; | |
| 46 | + | |
| 47 | + private boolean showDialog = false; | |
| 48 | + | |
| 49 | + public LoginManager(File jsonFile) | |
| 50 | + { | |
| 51 | + this.jsonFile = jsonFile; | |
| 52 | + | |
| 53 | + this.resetAuth(); | |
| 54 | + this.load(); | |
| 55 | + } | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * | |
| 59 | + */ | |
| 60 | + public void resetAuth() | |
| 61 | + { | |
| 62 | + this.authService = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); | |
| 63 | + this.authentication = new YggdrasilUserAuthentication(this.authService, Agent.MINECRAFT); | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * @throws JsonIOException | |
| 68 | + * @throws JsonSyntaxException | |
| 69 | + */ | |
| 70 | + private void load() | |
| 71 | + { | |
| 72 | + if (this.jsonFile.exists()) | |
| 73 | + { | |
| 74 | + FileReader fileReader = null; | |
| 75 | + | |
| 76 | + try | |
| 77 | + { | |
| 78 | + fileReader = new FileReader(this.jsonFile); | |
| 79 | + AuthData authData = LoginManager.gson.fromJson(fileReader, AuthData.class); | |
| 80 | + | |
| 81 | + if (authData != null) | |
| 82 | + { | |
| 83 | + this.logInfo("Initialising Yggdrasil authentication service with client token: %s", authData.getClientToken()); | |
| 84 | + this.authService = new YggdrasilAuthenticationService(Proxy.NO_PROXY, authData.getClientToken()); | |
| 85 | + this.authentication = new YggdrasilUserAuthentication(this.authService, Agent.MINECRAFT); | |
| 86 | + authData.loadFromStorage(this.authentication); | |
| 87 | + this.offline = authData.workOffline(); | |
| 88 | + this.defaultUsername = authData.getUsername(); | |
| 89 | + this.defaultDisplayName = authData.getDisplayName(); | |
| 90 | + } | |
| 91 | + } | |
| 92 | + catch (IOException ex) {} | |
| 93 | + finally | |
| 94 | + { | |
| 95 | + try | |
| 96 | + { | |
| 97 | + if (fileReader != null) fileReader.close(); | |
| 98 | + } | |
| 99 | + catch (IOException ex) {} | |
| 100 | + } | |
| 101 | + } | |
| 102 | + } | |
| 103 | + | |
| 104 | + private void save() | |
| 105 | + { | |
| 106 | + FileWriter fileWriter = null; | |
| 107 | + | |
| 108 | + try | |
| 109 | + { | |
| 110 | + fileWriter = new FileWriter(this.jsonFile); | |
| 111 | + | |
| 112 | + AuthData authData = new AuthData(this.authService, this.authentication, this.offline, this.defaultUsername, this.defaultDisplayName); | |
| 113 | + LoginManager.gson.toJson(authData, fileWriter); | |
| 114 | + } | |
| 115 | + catch (IOException ex) { ex.printStackTrace(); } | |
| 116 | + finally | |
| 117 | + { | |
| 118 | + try | |
| 119 | + { | |
| 120 | + if (fileWriter != null) fileWriter.close(); | |
| 121 | + } | |
| 122 | + catch (IOException ex) { ex.printStackTrace(); } | |
| 123 | + } | |
| 124 | + | |
| 125 | + } | |
| 126 | + | |
| 127 | + public boolean login(String username, String password, int remainingTries) | |
| 128 | + { | |
| 129 | + if (this.offline || remainingTries < 1) | |
| 130 | + { | |
| 131 | + this.logInfo("LoginManager is set to work offline, skipping login"); | |
| 132 | + return false; | |
| 133 | + } | |
| 134 | + | |
| 135 | + this.logInfo("Remaining login tries: %d", remainingTries); | |
| 136 | + | |
| 137 | + try | |
| 138 | + { | |
| 139 | + this.logInfo("Attempting login, contacting Mojang auth servers..."); | |
| 140 | + | |
| 141 | + this.authentication.logIn(); | |
| 142 | + | |
| 143 | + if (this.authentication.isLoggedIn()) | |
| 144 | + { | |
| 145 | + this.logInfo("LoginManager logged in successfully. Can play online = %s", this.authentication.canPlayOnline()); | |
| 146 | + this.save(); | |
| 147 | + return true; | |
| 148 | + } | |
| 149 | + | |
| 150 | + this.logInfo("LoginManager failed to log in, unspecified status."); | |
| 151 | + } | |
| 152 | + catch (InvalidCredentialsException ex) | |
| 153 | + { | |
| 154 | + this.logInfo("Authentication agent reported invalid credentials: %s", ex.getMessage()); | |
| 155 | + this.resetAuth(); | |
| 156 | + | |
| 157 | + if (username == null) | |
| 158 | + { | |
| 159 | + username = this.defaultUsername; | |
| 160 | + } | |
| 161 | + | |
| 162 | + if (this.showDialog || username == null || password == null) | |
| 163 | + { | |
| 164 | + LoginPanel loginPanel = LoginPanel.getLoginPanel(username, password, this.showDialog ? ex.getMessage() : null); | |
| 165 | + if (!loginPanel.showModalDialog()) | |
| 166 | + { | |
| 167 | + this.logInfo("User cancelled login dialog"); | |
| 168 | + this.offline = loginPanel.workOffline(); | |
| 169 | + if (this.offline) this.save(); | |
| 170 | + return false; | |
| 171 | + } | |
| 172 | + | |
| 173 | + username = loginPanel.getUsername(); | |
| 174 | + password = loginPanel.getPassword(); | |
| 175 | + this.offline = loginPanel.workOffline(); | |
| 176 | + this.save(); | |
| 177 | + } | |
| 178 | + | |
| 179 | + if (!Strings.isNullOrEmpty(username) && !Strings.isNullOrEmpty(password)) | |
| 180 | + { | |
| 181 | + this.authentication.setUsername(username); | |
| 182 | + this.authentication.setPassword(password); | |
| 183 | + } | |
| 184 | + | |
| 185 | + this.showDialog = true; | |
| 186 | + this.login(username, password, --remainingTries); | |
| 187 | + } | |
| 188 | + catch (AuthenticationException ex) | |
| 189 | + { | |
| 190 | + ex.printStackTrace(); | |
| 191 | + } | |
| 192 | + | |
| 193 | + this.save(); | |
| 194 | + return false; | |
| 195 | + } | |
| 196 | + | |
| 197 | + public String getProfileName() | |
| 198 | + { | |
| 199 | + GameProfile selectedProfile = this.authentication.getSelectedProfile(); | |
| 200 | + return selectedProfile != null ? selectedProfile.getName() : this.defaultDisplayName; | |
| 201 | + } | |
| 202 | + | |
| 203 | + public String getAuthenticatedToken() | |
| 204 | + { | |
| 205 | + String accessToken = this.authentication.getAuthenticatedToken(); | |
| 206 | + return accessToken != null ? accessToken : "-"; | |
| 207 | + } | |
| 208 | + | |
| 209 | + private void logInfo(String message, Object... params) | |
| 210 | + { | |
| 211 | + LoginManager.logger.info(String.format(message, params)); | |
| 212 | + } | |
| 213 | + | |
| 214 | + class AuthData | |
| 215 | + { | |
| 216 | + private String clientToken; | |
| 217 | + | |
| 218 | + private boolean workOffline; | |
| 219 | + | |
| 220 | + private Map<String, String> credentials; | |
| 221 | + | |
| 222 | + public AuthData() | |
| 223 | + { | |
| 224 | + } | |
| 225 | + | |
| 226 | + public AuthData(YggdrasilAuthenticationService authService, YggdrasilUserAuthentication authentication, boolean workOffline, String defaultUserName, String defaultDisplayName) | |
| 227 | + { | |
| 228 | + this.clientToken = authService.getClientToken(); | |
| 229 | + this.credentials = authentication.saveForStorage(); | |
| 230 | + this.workOffline = workOffline; | |
| 231 | + | |
| 232 | + if (defaultUserName != null && !this.credentials.containsKey("username")) | |
| 233 | + this.credentials.put("username", defaultUserName); | |
| 234 | + | |
| 235 | + if (defaultDisplayName != null && !this.credentials.containsKey("displayName")) | |
| 236 | + this.credentials.put("displayName", defaultDisplayName); | |
| 237 | + } | |
| 238 | + | |
| 239 | + public String getClientToken() | |
| 240 | + { | |
| 241 | + return this.clientToken; | |
| 242 | + } | |
| 243 | + | |
| 244 | + public void setClientToken(String clientToken) | |
| 245 | + { | |
| 246 | + this.clientToken = clientToken; | |
| 247 | + } | |
| 248 | + | |
| 249 | + public void loadFromStorage(YggdrasilUserAuthentication authentication) | |
| 250 | + { | |
| 251 | + authentication.loadFromStorage(this.credentials); | |
| 252 | + } | |
| 253 | + | |
| 254 | + public boolean workOffline() | |
| 255 | + { | |
| 256 | + return this.workOffline; | |
| 257 | + } | |
| 258 | + | |
| 259 | + public String getUsername() | |
| 260 | + { | |
| 261 | + return this.credentials != null ? this.credentials.get("username") : null; | |
| 262 | + } | |
| 263 | + | |
| 264 | + public String getDisplayName() | |
| 265 | + { | |
| 266 | + return this.credentials != null && this.credentials.containsKey("displayName") ? this.credentials.get("displayName") : System.getProperty("user.name"); | |
| 267 | + } | |
| 268 | + } | |
| 269 | +} | ... | ... |
debug/com/mumfrey/liteloader/debug/LoginPanel.java
0 → 100644
| 1 | +package com.mumfrey.liteloader.debug; | |
| 2 | + | |
| 3 | +import javax.swing.JPanel; | |
| 4 | + | |
| 5 | +import java.awt.Color; | |
| 6 | +import java.awt.Dimension; | |
| 7 | +import java.awt.BorderLayout; | |
| 8 | + | |
| 9 | +import javax.swing.JLabel; | |
| 10 | + | |
| 11 | +import java.awt.Font; | |
| 12 | + | |
| 13 | +import javax.swing.border.EmptyBorder; | |
| 14 | +import javax.swing.border.TitledBorder; | |
| 15 | +import javax.swing.JDialog; | |
| 16 | +import javax.swing.UIManager; | |
| 17 | +import javax.swing.JCheckBox; | |
| 18 | + | |
| 19 | +import java.awt.Component; | |
| 20 | +import java.awt.Container; | |
| 21 | +import java.awt.FlowLayout; | |
| 22 | +import java.awt.FocusTraversalPolicy; | |
| 23 | +import java.awt.TextField; | |
| 24 | +import java.awt.GridBagLayout; | |
| 25 | +import java.awt.GridBagConstraints; | |
| 26 | +import java.awt.Insets; | |
| 27 | + | |
| 28 | +import javax.swing.JButton; | |
| 29 | + | |
| 30 | +import java.awt.event.ActionListener; | |
| 31 | +import java.awt.event.ActionEvent; | |
| 32 | +import java.awt.event.WindowAdapter; | |
| 33 | +import java.awt.event.WindowEvent; | |
| 34 | +import java.util.ArrayList; | |
| 35 | +import java.util.List; | |
| 36 | + | |
| 37 | +import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * JPanel displayed in a JDialog to prompt the user for login credentials for minecraft | |
| 41 | + * | |
| 42 | + * @author Adam Mummery-Smith | |
| 43 | + */ | |
| 44 | +public class LoginPanel extends JPanel | |
| 45 | +{ | |
| 46 | + private static final long serialVersionUID = 1L; | |
| 47 | + private TextField txtUsername; | |
| 48 | + private TextField txtPassword; | |
| 49 | + private JButton btnLogin; | |
| 50 | + private JButton btnCancel; | |
| 51 | + | |
| 52 | + private boolean loginClicked = false; | |
| 53 | + | |
| 54 | + private JDialog dialog; | |
| 55 | + private JCheckBox chkOffline; | |
| 56 | + private JLabel lblLogIn; | |
| 57 | + private JPanel panelLogin; | |
| 58 | + private JPanel panelButtons; | |
| 59 | + private JPanel panelPadding; | |
| 60 | + private JLabel lblNewLabel; | |
| 61 | + private JLabel lblPassword; | |
| 62 | + | |
| 63 | + private CustomFocusTraversal tabOrder = new CustomFocusTraversal(); | |
| 64 | + private JLabel lblMessage; | |
| 65 | + | |
| 66 | + public LoginPanel(String username, String password, String error) | |
| 67 | + { | |
| 68 | + this.setFocusable(false); | |
| 69 | + this.setPreferredSize(new Dimension(400, 260)); | |
| 70 | + this.setBackground(new Color(105, 105, 105)); | |
| 71 | + this.setLayout(new BorderLayout(0, 0)); | |
| 72 | + | |
| 73 | + this.lblLogIn = new JLabel("Log In"); | |
| 74 | + this.lblLogIn.setFocusable(false); | |
| 75 | + this.lblLogIn.setBorder(new EmptyBorder(10, 16, 10, 16)); | |
| 76 | + this.lblLogIn.setOpaque(true); | |
| 77 | + this.lblLogIn.setBackground(new Color(119, 136, 153)); | |
| 78 | + this.lblLogIn.setFont(new Font("Tahoma", Font.BOLD, 18)); | |
| 79 | + this.lblLogIn.setForeground(new Color(255, 255, 255)); | |
| 80 | + this.lblLogIn.setPreferredSize(new Dimension(400, 64)); | |
| 81 | + this.add(this.lblLogIn, BorderLayout.NORTH); | |
| 82 | + | |
| 83 | + this.panelButtons = new JPanel(); | |
| 84 | + this.panelButtons.setFocusable(false); | |
| 85 | + this.panelButtons.setBackground(new Color(112, 128, 144)); | |
| 86 | + this.panelButtons.setPreferredSize(new Dimension(400, 32)); | |
| 87 | + this.add(this.panelButtons, BorderLayout.SOUTH); | |
| 88 | + this.panelButtons.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); | |
| 89 | + | |
| 90 | + this.chkOffline = new JCheckBox("Never ask me to log in (always run offline)"); | |
| 91 | + this.chkOffline.setPreferredSize(new Dimension(386, 23)); | |
| 92 | + this.chkOffline.setForeground(new Color(255, 255, 255)); | |
| 93 | + this.chkOffline.setOpaque(false); | |
| 94 | + this.panelButtons.add(this.chkOffline); | |
| 95 | + | |
| 96 | + this.panelPadding = new JPanel(); | |
| 97 | + this.panelPadding.setFocusable(false); | |
| 98 | + this.panelPadding.setBorder(new EmptyBorder(4, 8, 8, 8)); | |
| 99 | + this.panelPadding.setOpaque(false); | |
| 100 | + this.add(this.panelPadding, BorderLayout.CENTER); | |
| 101 | + this.panelPadding.setLayout(new BorderLayout(0, 0)); | |
| 102 | + | |
| 103 | + this.panelLogin = new JPanel(); | |
| 104 | + this.panelLogin.setFocusable(false); | |
| 105 | + this.panelPadding.add(this.panelLogin); | |
| 106 | + this.panelLogin.setOpaque(false); | |
| 107 | + this.panelLogin.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Yggdrasil Login", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(255, 255, 255))); | |
| 108 | + GridBagLayout gbl_panelLogin = new GridBagLayout(); | |
| 109 | + gbl_panelLogin.columnWidths = new int[] {30, 80, 120, 120, 30}; | |
| 110 | + gbl_panelLogin.rowHeights = new int[] {24, 32, 32, 32}; | |
| 111 | + gbl_panelLogin.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE}; | |
| 112 | + gbl_panelLogin.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0}; | |
| 113 | + this.panelLogin.setLayout(gbl_panelLogin); | |
| 114 | + | |
| 115 | + this.btnLogin = new JButton("Log in"); | |
| 116 | + this.btnLogin.addActionListener(new ActionListener() { | |
| 117 | + @Override public void actionPerformed(ActionEvent e) { | |
| 118 | + LoginPanel.this.onLoginClick(); | |
| 119 | + } | |
| 120 | + }); | |
| 121 | + | |
| 122 | + this.btnCancel = new JButton("Cancel"); | |
| 123 | + this.btnCancel.addActionListener(new ActionListener() { | |
| 124 | + @Override public void actionPerformed(ActionEvent e) { | |
| 125 | + LoginPanel.this.onCancelClick(); | |
| 126 | + } | |
| 127 | + }); | |
| 128 | + | |
| 129 | + this.lblMessage = new JLabel("Enter your login details for minecraft.net"); | |
| 130 | + this.lblMessage.setForeground(new Color(255, 255, 255)); | |
| 131 | + GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints(); | |
| 132 | + gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST; | |
| 133 | + gbc_lblNewLabel_1.gridwidth = 2; | |
| 134 | + gbc_lblNewLabel_1.insets = new Insets(0, 0, 5, 5); | |
| 135 | + gbc_lblNewLabel_1.gridx = 2; | |
| 136 | + gbc_lblNewLabel_1.gridy = 0; | |
| 137 | + this.panelLogin.add(this.lblMessage, gbc_lblNewLabel_1); | |
| 138 | + | |
| 139 | + this.lblNewLabel = new JLabel("User name"); | |
| 140 | + this.lblNewLabel.setFocusable(false); | |
| 141 | + this.lblNewLabel.setForeground(new Color(255, 255, 255)); | |
| 142 | + GridBagConstraints gbc_lblNewLabel = new GridBagConstraints(); | |
| 143 | + gbc_lblNewLabel.anchor = GridBagConstraints.WEST; | |
| 144 | + gbc_lblNewLabel.fill = GridBagConstraints.VERTICAL; | |
| 145 | + gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5); | |
| 146 | + gbc_lblNewLabel.gridx = 1; | |
| 147 | + gbc_lblNewLabel.gridy = 1; | |
| 148 | + this.panelLogin.add(this.lblNewLabel, gbc_lblNewLabel); | |
| 149 | + | |
| 150 | + this.txtUsername = new TextField(); | |
| 151 | + this.txtUsername.setPreferredSize(new Dimension(200, 22)); | |
| 152 | + this.txtUsername.setText(username); | |
| 153 | + GridBagConstraints gbc_txtUsername = new GridBagConstraints(); | |
| 154 | + gbc_txtUsername.gridwidth = 2; | |
| 155 | + gbc_txtUsername.fill = GridBagConstraints.HORIZONTAL; | |
| 156 | + gbc_txtUsername.insets = new Insets(0, 0, 5, 0); | |
| 157 | + gbc_txtUsername.gridx = 2; | |
| 158 | + gbc_txtUsername.gridy = 1; | |
| 159 | + this.panelLogin.add(this.txtUsername, gbc_txtUsername); | |
| 160 | + | |
| 161 | + this.lblPassword = new JLabel("Password"); | |
| 162 | + this.lblPassword.setFocusable(false); | |
| 163 | + this.lblPassword.setForeground(Color.WHITE); | |
| 164 | + GridBagConstraints gbc_lblPassword = new GridBagConstraints(); | |
| 165 | + gbc_lblPassword.anchor = GridBagConstraints.WEST; | |
| 166 | + gbc_lblPassword.fill = GridBagConstraints.VERTICAL; | |
| 167 | + gbc_lblPassword.insets = new Insets(0, 0, 5, 5); | |
| 168 | + gbc_lblPassword.gridx = 1; | |
| 169 | + gbc_lblPassword.gridy = 2; | |
| 170 | + this.panelLogin.add(this.lblPassword, gbc_lblPassword); | |
| 171 | + | |
| 172 | + this.txtPassword = new TextField(); | |
| 173 | + this.txtPassword.setEchoChar('*'); | |
| 174 | + this.txtPassword.setPreferredSize(new Dimension(200, 22)); | |
| 175 | + this.txtPassword.setText(password); | |
| 176 | + GridBagConstraints gbc_txtPassword = new GridBagConstraints(); | |
| 177 | + gbc_txtPassword.gridwidth = 2; | |
| 178 | + gbc_txtPassword.insets = new Insets(0, 0, 5, 0); | |
| 179 | + gbc_txtPassword.fill = GridBagConstraints.HORIZONTAL; | |
| 180 | + gbc_txtPassword.gridx = 2; | |
| 181 | + gbc_txtPassword.gridy = 2; | |
| 182 | + this.panelLogin.add(this.txtPassword, gbc_txtPassword); | |
| 183 | + GridBagConstraints gbc_btnCancel = new GridBagConstraints(); | |
| 184 | + gbc_btnCancel.anchor = GridBagConstraints.EAST; | |
| 185 | + gbc_btnCancel.insets = new Insets(0, 0, 0, 5); | |
| 186 | + gbc_btnCancel.gridx = 2; | |
| 187 | + gbc_btnCancel.gridy = 3; | |
| 188 | + this.panelLogin.add(this.btnCancel, gbc_btnCancel); | |
| 189 | + GridBagConstraints gbc_btnLogin = new GridBagConstraints(); | |
| 190 | + gbc_btnLogin.fill = GridBagConstraints.HORIZONTAL; | |
| 191 | + gbc_btnLogin.gridx = 3; | |
| 192 | + gbc_btnLogin.gridy = 3; | |
| 193 | + this.panelLogin.add(this.btnLogin, gbc_btnLogin); | |
| 194 | + | |
| 195 | + this.tabOrder.add(this.txtUsername); | |
| 196 | + this.tabOrder.add(this.txtPassword); | |
| 197 | + this.tabOrder.add(this.btnLogin); | |
| 198 | + this.tabOrder.add(this.btnCancel); | |
| 199 | + this.tabOrder.add(this.chkOffline); | |
| 200 | + | |
| 201 | + if (error != null) | |
| 202 | + { | |
| 203 | + this.lblMessage.setText(error); | |
| 204 | + this.lblMessage.setForeground(new Color(255, 180, 180)); | |
| 205 | + } | |
| 206 | + } | |
| 207 | + | |
| 208 | + protected void onShowDialog() | |
| 209 | + { | |
| 210 | + if (this.txtUsername.getText().length() > 0) | |
| 211 | + { | |
| 212 | + if (this.txtPassword.getText().length() > 0) | |
| 213 | + this.txtUsername.select(0, this.txtUsername.getText().length()); | |
| 214 | + else | |
| 215 | + this.txtPassword.requestFocusInWindow(); | |
| 216 | + } | |
| 217 | + } | |
| 218 | + | |
| 219 | + protected void onLoginClick() | |
| 220 | + { | |
| 221 | + this.loginClicked = true; | |
| 222 | + this.dialog.setVisible(false); | |
| 223 | + } | |
| 224 | + | |
| 225 | + protected void onCancelClick() | |
| 226 | + { | |
| 227 | + this.dialog.setVisible(false); | |
| 228 | + } | |
| 229 | + | |
| 230 | + /** | |
| 231 | + * @param dialog | |
| 232 | + * @param panel | |
| 233 | + */ | |
| 234 | + public void setDialog(JDialog dialog) | |
| 235 | + { | |
| 236 | + this.dialog = dialog; | |
| 237 | + | |
| 238 | + this.dialog.addWindowListener(new WindowAdapter() | |
| 239 | + { | |
| 240 | + @Override | |
| 241 | + public void windowOpened(WindowEvent e) | |
| 242 | + { | |
| 243 | + LoginPanel.this.onShowDialog(); | |
| 244 | + } | |
| 245 | + }); | |
| 246 | + | |
| 247 | + this.dialog.getRootPane().setDefaultButton(this.btnLogin); | |
| 248 | + this.dialog.setFocusTraversalPolicy(this.tabOrder); | |
| 249 | + } | |
| 250 | + | |
| 251 | + public boolean showModalDialog() | |
| 252 | + { | |
| 253 | + this.dialog.setVisible(true); | |
| 254 | + this.dialog.dispose(); | |
| 255 | + return this.loginClicked; | |
| 256 | + } | |
| 257 | + | |
| 258 | + public String getUsername() | |
| 259 | + { | |
| 260 | + return this.txtUsername.getText(); | |
| 261 | + } | |
| 262 | + | |
| 263 | + public String getPassword() | |
| 264 | + { | |
| 265 | + return this.txtPassword.getText(); | |
| 266 | + } | |
| 267 | + | |
| 268 | + public boolean workOffline() | |
| 269 | + { | |
| 270 | + return this.chkOffline.isSelected(); | |
| 271 | + } | |
| 272 | + | |
| 273 | + public static LoginPanel getLoginPanel(String username, String password, String error) | |
| 274 | + { | |
| 275 | + if (username == null) username = ""; | |
| 276 | + if (password == null) password = ""; | |
| 277 | + | |
| 278 | + final JDialog dialog = new JDialog(); | |
| 279 | + final LoginPanel panel = new LoginPanel(username, password, error); | |
| 280 | + panel.setDialog(dialog); | |
| 281 | + | |
| 282 | + dialog.setContentPane(panel); | |
| 283 | + dialog.setTitle("Yggdrasil Login"); | |
| 284 | + dialog.setResizable(false); | |
| 285 | + dialog.pack(); | |
| 286 | + dialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE); | |
| 287 | + dialog.setLocationRelativeTo(null); | |
| 288 | + dialog.setModal(true); | |
| 289 | + | |
| 290 | + return panel; | |
| 291 | + } | |
| 292 | + | |
| 293 | + class CustomFocusTraversal extends FocusTraversalPolicy | |
| 294 | + { | |
| 295 | + private final List<Component> components = new ArrayList<Component>(); | |
| 296 | + | |
| 297 | + void add(Component component) | |
| 298 | + { | |
| 299 | + this.components.add(component); | |
| 300 | + } | |
| 301 | + | |
| 302 | + @Override | |
| 303 | + public Component getComponentAfter(Container container, Component component) | |
| 304 | + { | |
| 305 | + int index = this.components.indexOf(component) + 1; | |
| 306 | + if (index >= this.components.size()) return this.components.get(0); | |
| 307 | + return this.components.get(index); | |
| 308 | + } | |
| 309 | + | |
| 310 | + @Override | |
| 311 | + public Component getComponentBefore(Container container, Component component) | |
| 312 | + { | |
| 313 | + int index = this.components.indexOf(component) - 1; | |
| 314 | + if (index < 0) return this.getLastComponent(container); | |
| 315 | + return this.components.get(index); | |
| 316 | + } | |
| 317 | + | |
| 318 | + @Override | |
| 319 | + public Component getFirstComponent(Container container) | |
| 320 | + { | |
| 321 | + return this.components.get(0); | |
| 322 | + } | |
| 323 | + | |
| 324 | + @Override | |
| 325 | + public Component getLastComponent(Container container) | |
| 326 | + { | |
| 327 | + return this.components.get(this.components.size() - 1); | |
| 328 | + } | |
| 329 | + | |
| 330 | + @Override | |
| 331 | + public Component getDefaultComponent(Container container) | |
| 332 | + { | |
| 333 | + return this.getFirstComponent(container); | |
| 334 | + } | |
| 335 | + } | |
| 336 | +} | ... | ... |
debug/com/mumfrey/liteloader/debug/Start.java
| 1 | 1 | package com.mumfrey.liteloader.debug; |
| 2 | 2 | import java.io.File; |
| 3 | -import java.io.IOException; | |
| 4 | -import java.net.Proxy; | |
| 5 | -import java.net.URL; | |
| 3 | +import java.util.logging.Logger; | |
| 6 | 4 | |
| 7 | -import net.minecraft.hopper.Util; | |
| 8 | -import net.minecraft.launcher.authentication.yggdrasil.AuthenticationResponse; | |
| 9 | 5 | import net.minecraft.launchwrapper.Launch; |
| 10 | 6 | |
| 11 | -import org.apache.commons.lang3.StringUtils; | |
| 12 | - | |
| 13 | -import com.google.gson.Gson; | |
| 14 | 7 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; |
| 15 | 8 | |
| 16 | 9 | /** |
| 17 | 10 | * Wrapper class for LaunchWrapper Main class, which logs into minecraft.net first so that online shizzle can be tested |
| 18 | 11 | * |
| 19 | 12 | * @author Adam Mummery-Smith |
| 20 | - * @version 0.5 | |
| 13 | + * @version 0.6 | |
| 21 | 14 | */ |
| 22 | 15 | public abstract class Start |
| 23 | 16 | { |
| 24 | - /** | |
| 25 | - * Username specified on the command line | |
| 26 | - */ | |
| 27 | - private static String userName = ""; | |
| 17 | + private static Logger logger = Logger.getLogger("liteloader"); | |
| 28 | 18 | |
| 29 | 19 | /** |
| 30 | - * Session ID retrieved during login ("-" means no session, eg. offline) | |
| 31 | - */ | |
| 32 | - private static String sessionId = "-"; | |
| 33 | - | |
| 34 | - /** | |
| 35 | - * Entry point. Validates the parameters and performs the login | |
| 20 | + * Entry point. | |
| 36 | 21 | * |
| 37 | 22 | * @param args |
| 38 | 23 | */ |
| 39 | 24 | public static void main(String[] args) |
| 40 | 25 | { |
| 41 | - // Check we have enough arguments | |
| 42 | - if (args.length < 2) | |
| 43 | - { | |
| 44 | - Start.showError("Invalid parameters specified for start, use: <username> <password> to log in to minecraft.net"); | |
| 45 | - userName = args.length < 1 ? System.getProperty("user.name") : args[0]; | |
| 46 | - } | |
| 47 | - else | |
| 48 | - { | |
| 49 | - // Assign username as the first argument | |
| 50 | - userName = args[0]; | |
| 51 | - | |
| 52 | - // Perform the login if the second parameter is not "-" (indicating offline) | |
| 53 | - if (!args[1].equals("-") && Start.login(args[0], args[1], 13, true)) | |
| 54 | - { | |
| 55 | - Start.showMessage(String.format("Successfully logged in as %s with session ID %s", userName, sessionId)); | |
| 56 | - args[0] = userName; | |
| 57 | - args[1] = sessionId; | |
| 58 | - } | |
| 59 | - } | |
| 26 | + String usernameFromCmdLine = (args.length > 0) ? args[0] : null; | |
| 27 | + String passwordFromCmdLine = (args.length > 1) ? args[1] : null; | |
| 28 | + | |
| 29 | + File loginJson = new File(new File(System.getProperty("user.dir")), ".auth.json"); | |
| 30 | + LoginManager loginManager = new LoginManager(loginJson); | |
| 31 | + loginManager.login(usernameFromCmdLine, passwordFromCmdLine, 5); | |
| 60 | 32 | |
| 61 | - Start.showMessage(String.format("Launching game as %s", userName)); | |
| 33 | + Start.logger.info(String.format("Launching game as %s", loginManager.getProfileName())); | |
| 62 | 34 | |
| 63 | 35 | File gameDir = new File(System.getProperty("user.dir")); |
| 64 | 36 | File assetsDir = new File(gameDir, "assets"); |
| 65 | 37 | |
| 66 | 38 | args = new String[] { |
| 67 | 39 | "--tweakClass", LiteLoaderTweaker.class.getName(), |
| 68 | - "--username", userName, | |
| 69 | - "--session", sessionId, | |
| 40 | + "--username", loginManager.getProfileName(), | |
| 41 | + "--session", loginManager.getAuthenticatedToken(), | |
| 70 | 42 | "--version", "mcp", |
| 71 | 43 | "--gameDir", gameDir.getAbsolutePath(), |
| 72 | 44 | "--assetsDir", assetsDir.getAbsolutePath() |
| ... | ... | @@ -74,60 +46,4 @@ public abstract class Start |
| 74 | 46 | |
| 75 | 47 | Launch.main(args); |
| 76 | 48 | } |
| 77 | - | |
| 78 | - private static boolean login(String user, String password, int masqueradeLauncherVersion, boolean validateCertificate) | |
| 79 | - { | |
| 80 | - try | |
| 81 | - { | |
| 82 | - AuthenticationResponse response = Start.authRequest(user, password); | |
| 83 | - | |
| 84 | - if (response != null) | |
| 85 | - { | |
| 86 | - userName = response.getSelectedProfile().getName(); | |
| 87 | - sessionId = String.format("token:%s:%s", response.getAccessToken(), response.getSelectedProfile().getId()); | |
| 88 | - return true; | |
| 89 | - } | |
| 90 | - } | |
| 91 | - catch (Exception ex) {} | |
| 92 | - | |
| 93 | - return false; | |
| 94 | - } | |
| 95 | - | |
| 96 | - protected static AuthenticationResponse authRequest(String user, String password) throws IOException | |
| 97 | - { | |
| 98 | - Gson gson = new Gson(); | |
| 99 | - AuthenticationRequest request = new AuthenticationRequest(user, password); | |
| 100 | - URL authUrl = new URL("https://authserver.mojang.com/authenticate"); | |
| 101 | - String json = Util.performPost(authUrl, gson.toJson(request), Proxy.NO_PROXY, "application/json", true); | |
| 102 | - AuthenticationResponse result = gson.fromJson(json, AuthenticationResponse.class); | |
| 103 | - if (result != null) | |
| 104 | - { | |
| 105 | - if (StringUtils.isBlank(result.getError())) | |
| 106 | - return result; | |
| 107 | - | |
| 108 | - Start.showError(result.getErrorMessage()); | |
| 109 | - } | |
| 110 | - | |
| 111 | - return null; | |
| 112 | - } | |
| 113 | - | |
| 114 | - /** | |
| 115 | - * Show a message on stdout | |
| 116 | - * | |
| 117 | - * @param message | |
| 118 | - */ | |
| 119 | - private static void showMessage(String message) | |
| 120 | - { | |
| 121 | - System.out.println("[START] [INFO] " + message); | |
| 122 | - } | |
| 123 | - | |
| 124 | - /** | |
| 125 | - * Show a message on stderr | |
| 126 | - * | |
| 127 | - * @param message | |
| 128 | - */ | |
| 129 | - private static void showError(String message) | |
| 130 | - { | |
| 131 | - System.err.println("[START] [ERROR] " + message); | |
| 132 | - } | |
| 133 | 49 | } | ... | ... |
debug/minecraft.key deleted
100644 → 0
No preview for this file type
javadoc/guava-14.0.1-javadoc.jar deleted
100644 → 0
No preview for this file type
javadoc/jopt-simple-4.5-javadoc.jar deleted
100644 → 0
No preview for this file type
lib/authlib-1.3.jar
0 → 100644
No preview for this file type
lib/jopt-simple-4.5.jar deleted
100644 → 0
No preview for this file type
lib/launcher.jar deleted
100644 → 0
No preview for this file type
lib/log4j-api-2.0-beta9.jar
0 → 100644
No preview for this file type
lib/log4j-core-2.0-beta9.jar
0 → 100644
No preview for this file type