Commit 89fcc90e9348ddc09fd21a4c4f6430065689cdb7

Authored by Mumfrey
1 parent f11271d2

LiteLoader 1.6.3 - Updated Start to use Yggsdrasil and improvements to build script

.classpath
... ... @@ -10,6 +10,6 @@
10 10 <classpathentry kind="lib" path="/Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar"/>
11 11 <classpathentry exported="true" kind="lib" path="lib/launchwrapper-1.7.jar"/>
12 12 <classpathentry kind="lib" path="lib/jopt-simple-4.5.jar"/>
13   - <classpathentry kind="src" path="run"/>
  13 + <classpathentry exported="true" kind="lib" path="lib/launcher.jar"/>
14 14 <classpathentry kind="output" path="bin"/>
15 15 </classpath>
... ...
ant/build_liteloader.xml
... ... @@ -2,75 +2,143 @@
2 2 <project name="liteloader" basedir="." default="rebuild">
3 3  
4 4 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
5   -
6   - <!-- Versions !!IMPORTANT -->
  5 +
  6 + <!-- Versions !!IMPORTANT -->
7 7 <property name="version" value="1.6.3" />
8   - <property name="mcversion" value="1.6.3" />
9   - <property name="author" value="Mumfrey" />
10   -
11   - <!-- Project definitions and dependencies -->
  8 + <property name="mcversion" value="1.6.3" />
  9 + <property name="author" value="Mumfrey" />
  10 +
  11 + <!-- Project definitions and dependencies -->
12 12 <property name="upstream" value="" />
13 13 <property name="project" value="LiteLoader" />
14 14 <property name="md5set" value="mcp" />
15   - <property name="outmd5set" value="liteloader" />
16   -
  15 + <property name="outmd5set" value="liteloader" />
  16 +
17 17 <property name="mcp.dir" location="../../.." />
18   - <property name="build" location="${mcp.dir}/build" />
19   - <property name="eclipse" location="${mcp.dir}/eclipse" />
20   - <property name="src" location="${mcp.dir}/src/minecraft" />
21   - <property name="temp" location="${mcp.dir}/temp" />
22   - <property name="md5.dir" location="${mcp.dir}/md5" />
23   - <property name="mc.src" location="${mcp.dir}/src/mcp" />
24   - <property name="libs" location="${mcp.dir}/lib" />
  18 + <property name="build" location="${mcp.dir}/build" />
  19 + <property name="eclipse" location="${mcp.dir}/eclipse" />
  20 + <property name="src" location="${mcp.dir}/src/minecraft" />
  21 + <property name="temp" location="${mcp.dir}/temp" />
  22 + <property name="md5.dir" location="${mcp.dir}/md5" />
  23 + <property name="mc.src" location="${mcp.dir}/src/mcp" />
  24 + <property name="libs" location="${mcp.dir}/lib" />
25 25  
26 26 <property name="dist.dir" location="${build}/dist" />
27 27 <property name="stage.dir" location="${build}/stage/${ant.project.name}/${version}" />
28   - <property name="filetype" value="jar" />
  28 + <property name="filetype" value="jar" />
29 29  
30 30 <property name="python" location="${mcp.dir}/runtime/bin/python/python_mcp.exe" />
31 31  
  32 + <target name="findmcp">
  33 + <echo level="info" message="Searching for clean MCP source..." />
  34 + <condition property="mcpsrc.exists">
  35 + <available file="${mc.src}" type="dir"/>
  36 + </condition>
  37 + </target>
  38 +
32 39 <!-- Main target -->
33   - <target name="rebuild" description="Perform all tasks for a build" depends="init, recompile, reobfuscate, savemd5, stage, zip" />
  40 + <target name="rebuild" depends="findmcp" description="Entry point">
  41 + <antcall target="nobuild" />
  42 + <antcall target="build" />
  43 + </target>
34 44  
35   - <target name="clean">
36   - <delete dir="${src}" />
37   - <delete dir="${mcp.dir}/reobf" />
  45 + <target name="nobuild" description="Notify the user that they done goofed" unless="mcpsrc.exists">
  46 + <echo level="info" message="--------------------------------------------------------------------------------" />
  47 + <echo level="info" message=" " />
  48 + <echo level="info" message=" #NOPE!" />
  49 + <echo level="info" message=" " />
  50 + <echo level="info" message=" LiteLoader build uses the MCP src/minecraft directory as the target for source" />
  51 + <echo level="info" message=" aggregation so that MCP can be called without modifications. This means that" />
  52 + <echo level="info" message=" before you start you MUST copy the decompiled sources to src/mcp so that the" />
  53 + <echo level="info" message=" LiteLoader build script has a clean base to work from." />
  54 + <echo level="info" message=" " />
  55 + <echo level="info" message=" To rectify this problem and allow the loader to build:" />
  56 + <echo level="info" message=" " />
  57 + <echo level="info" message=" + Run the MCP decompile process so that clean sources end up in src/minecraft" />
  58 + <echo level="info" message=" + RENAME the src/minecraft folder to src/mcp" />
  59 + <echo level="info" message=" + Run this builder again, the builder will create a clean MD5 set for the" />
  60 + <echo level="info" message=" clean sources" />
  61 + <echo level="info" message=" " />
  62 + <echo level="info" message=" If you have already performed the above steps, and it's still not working, then" />
  63 + <echo level="info" message=" it's probably time to learn ant scripting and figure out why." />
  64 + <echo level="info" message=" " />
  65 + <echo level="info" message=" Never give up; never surrender!" />
  66 + <echo level="info" message=" " />
  67 + <echo level="info" message="--------------------------------------------------------------------------------" />
38 68 </target>
39   -
  69 +
  70 + <target name="build" description="Perform all tasks for a build" if="mcpsrc.exists">
  71 + <antcall target="init" />
  72 + <antcall target="recompile" />
  73 + <antcall target="reobfuscate" />
  74 + <antcall target="savemd5" />
  75 + <antcall target="stage" />
  76 + <antcall target="zip" />
  77 + </target>
  78 +
  79 + <target name="clean">
  80 + <echo level="info" message="Cleaning output directories" />
  81 +
  82 + <delete dir="${src}" />
  83 + <delete dir="${mcp.dir}/reobf" />
  84 + </target>
  85 +
40 86 <target name="contributesource" description="Contribute an upstream project source code to the source path">
41 87 <echo level="info" message="Contributing project ${lib}" />
42   - <copy todir="${src}" verbose="false" overwrite="true" failonerror="false">
43   - <fileset dir="${eclipse}/${lib}/java" />
44   - <fileset dir="${eclipse}/${lib}/src" />
45   - </copy>
  88 + <copy todir="${src}" verbose="false" overwrite="true" failonerror="false">
  89 + <fileset dir="${eclipse}/${lib}/java">
  90 + <exclude name="**/debug" />
  91 + <exclude name="**/debug/*.java" />
  92 + </fileset>
  93 + <fileset dir="${eclipse}/${lib}/src" />
  94 + </copy>
  95 + </target>
  96 +
  97 + <target name="contributeresources" description="Contribute resources to the staging path">
  98 + <echo level="info" message="Contributing project resources for ${lib}" />
  99 + <copy todir="${stage.dir}" verbose="false" failonerror="false">
  100 + <fileset dir="${eclipse}/${lib}/res" excludes=".svn/**">
  101 + <exclude name="**/Thumbs.db" />
  102 + <exclude name="**/minecraft.key" />
  103 + </fileset>
  104 + </copy>
  105 + </target>
  106 +
  107 + <target name="findmd5">
  108 + <echo level="info" message="Searching for existing MD5 sets..." />
  109 + <condition property="md5dir.exists">
  110 + <available file="${md5.dir}" type="dir"/>
  111 + </condition>
  112 + </target>
  113 +
  114 + <target name="seedmd5" depends="findmd5" unless="md5dir.exists">
  115 + <echo level="info" message="MD5 sets not found, seeding..." />
  116 + <ant target="genmd5" antfile="seed_md5.xml" inheritall="false" />
46 117 </target>
47   -
48   - <target name="contributeresources" description="Contribute resources to the staging path">
49   - <echo level="info" message="Contributing project resources for ${lib}" />
50   - <copy todir="${stage.dir}" verbose="false" failonerror="false">
51   - <fileset dir="${eclipse}/${lib}/res" excludes=".svn/**">
52   - <exclude name="**/Thumbs.db" />
53   - </fileset>
54   - </copy>
55   - </target>
56   -
57   - <target name="preparemd5" description="Copy patched MD5 to the temp directory" depends="clean">
58   - <echo level="info" message="Prepare exclusion MD5s, using exclusion set &quot;${md5set}&quot;" />
59 118  
60   - <copy tofile="${temp}/client.md5" file="${md5.dir}/client_${md5set}.md5" failonerror="true" verbose="true" overwrite="true" />
  119 + <target name="notifymd5ok" depends="findmd5" if="md5dir.exists">
  120 + <echo level="info" message="MD5 sets already exist, skipping MD5 set seeding" />
61 121 </target>
62   -
  122 +
  123 + <target name="preparemd5" description="Copy patched MD5 to the temp directory" depends="seedmd5, notifymd5ok, clean">
  124 + <echo level="info" message="Prepare exclusion MD5s, using exclusion set &quot;${md5set}&quot;" />
  125 +
  126 + <copy tofile="${temp}/client.md5" file="${md5.dir}/client_${md5set}.md5" failonerror="true" verbose="true" overwrite="true" />
  127 + </target>
  128 +
63 129 <target name="prepare" description="Prepare source for MCP" depends="preparemd5">
64   - <echo level="info" message="Prepare sources for compile" />
  130 + <echo level="info" message="Prepare sources for compile" />
65 131  
66   - <copy todir="${libs}" verbose="true" overwrite="true">
67   - <fileset dir="${eclipse}/LiteLoader/lib" />
68   - </copy>
69   -
70   - <copy todir="${src}" verbose="false" overwrite="true">
  132 + <copy todir="${libs}" verbose="true" overwrite="true">
  133 + <fileset dir="${eclipse}/LiteLoader/lib">
  134 + <exclude name="**/launcher.jar" />
  135 + </fileset>
  136 + </copy>
  137 +
  138 + <copy todir="${src}" verbose="false" overwrite="true">
71 139 <fileset dir="${mc.src}" />
72 140 </copy>
73   -
  141 +
74 142 <foreach list="${upstream}" param="lib" target="contributesource" />
75 143  
76 144 <antcall target="contributesource">
... ... @@ -90,7 +158,7 @@
90 158 </target>
91 159  
92 160 <target name="recompile" description="MCP recompile">
93   - <echo level="info" message="Compiling projects" />
  161 + <echo level="info" message="Compiling projects" />
94 162  
95 163 <exec executable="${python}" dir="${mcp.dir}">
96 164 <arg value="runtime/recompile.py" />
... ... @@ -100,38 +168,38 @@
100 168 </target>
101 169  
102 170 <target name="reobfuscate" description="MCP reobfuscate">
103   - <echo level="info" message="Obfuscating classes" />
  171 + <echo level="info" message="Obfuscating classes" />
104 172  
105 173 <exec executable="${python}" dir="${mcp.dir}">
106 174 <arg value="runtime/reobfuscate.py" />
107   - <arg value="--client" />
  175 + <arg value="--client" />
108 176 <arg value="%*" />
109 177 </exec>
110 178 </target>
111   -
112   - <target name="savemd5" description="Put post-obfuscation MD5 to stored md5 set" if="outmd5set">
113   - <echo level="info" message="Storing obfuscated MD5s" />
  179 +
  180 + <target name="savemd5" description="Put post-obfuscation MD5 to stored md5 set" if="outmd5set">
  181 + <echo level="info" message="Storing obfuscated MD5s" />
114 182  
115 183 <copy file="${temp}/client_reobf.md5" tofile="${md5.dir}/client_${outmd5set}.md5" overwrite="true" verbose="true" />
116 184 </target>
117 185  
118 186 <target name="stage" description="Stage resources into staging directory">
119   - <echo level="info" message="Staging resources" />
  187 + <echo level="info" message="Staging resources" />
120 188  
121 189 <copy todir="${stage.dir}">
122 190 <fileset dir="${mcp.dir}/reobf/minecraft" excludes=".svn/**, *.txt" />
123 191 </copy>
124 192  
125   - <foreach list="${upstream}" param="lib" target="contributeresources" />
  193 + <foreach list="${upstream}" param="lib" target="contributeresources" />
  194 +
  195 + <antcall target="contributeresources">
  196 + <param name="lib" value="${project}" />
  197 + </antcall>
126 198  
127   - <antcall target="contributeresources">
128   - <param name="lib" value="${project}" />
129   - </antcall>
130   -
131 199 </target>
132 200  
133 201 <target name="zip" description="Build the output zip file">
134   - <echo level="info" message="Building final output" />
  202 + <echo level="info" message="Building final output" />
135 203  
136 204 <mkdir dir="${dist.dir}" />
137 205 <jar destfile="${dist.dir}/${ant.project.name}-${mcversion}.${filetype}" duplicate="preserve" index="true" manifestencoding="UTF-8">
... ...
ant/seed_md5.xml 0 โ†’ 100644
  1 +<?xml version="1.0" encoding="UTF-8" ?>
  2 +<project name="mcp" basedir="." default="genmd5">
  3 +
  4 + <!-- ========================================================================== -->
  5 + <!-- DO NOT RUN THIS SCRIPT DIRECTLY -->
  6 + <!-- ========================================================================== -->
  7 +
  8 + <!-- This script is called by the LiteLoader build script if the initial MD5s -->
  9 + <!-- are missing. If you want to fire this script then delete the 'md5' folder -->
  10 + <!-- before running the LiteLoader build. -->
  11 +
  12 + <property name="outmd5set" value="mcp" />
  13 + <property name="mcp.dir" location="../../.." />
  14 + <property name="src" location="${mcp.dir}/src/minecraft" />
  15 + <property name="temp" location="${mcp.dir}/temp" />
  16 + <property name="md5.dir" location="${mcp.dir}/md5" />
  17 + <property name="mc.src" location="${mcp.dir}/src/mcp" />
  18 +
  19 + <property name="python" location="${mcp.dir}/runtime/bin/python/python_mcp.exe" />
  20 +
  21 + <target name="genmd5" description="Seed the initial MCP md5 set">
  22 + <echo level="info" message="MCP md5set was not found, making a clean compile" />
  23 + <antcall target="clean" />
  24 + <antcall target="init" />
  25 + <antcall target="recompile" />
  26 + <antcall target="reobfuscate" />
  27 + <antcall target="savemd5" />
  28 + </target>
  29 +
  30 + <target name="clean">
  31 + <echo level="info" message="Cleaning output directories" />
  32 +
  33 + <delete dir="${src}" />
  34 + <delete dir="${mcp.dir}/reobf" />
  35 + </target>
  36 +
  37 + <target name="init" description="Initialize environment">
  38 + <echo level="info" message="Initialising environment" />
  39 +
  40 + <mkdir dir="${md5.dir}" />
  41 +
  42 + <copy todir="${src}" verbose="false" overwrite="true">
  43 + <fileset dir="${mc.src}" />
  44 + </copy>
  45 + </target>
  46 +
  47 + <target name="recompile" description="MCP recompile">
  48 + <echo level="info" message="Compiling MCP sources" />
  49 +
  50 + <exec executable="${python}" dir="${mcp.dir}">
  51 + <arg value="runtime/recompile.py" />
  52 + <arg value="--client" />
  53 + <arg value="%*" />
  54 + </exec>
  55 + </target>
  56 +
  57 + <target name="reobfuscate" description="MCP reobfuscate">
  58 + <echo level="info" message="Obfuscating classes" />
  59 +
  60 + <exec executable="${python}" dir="${mcp.dir}">
  61 + <arg value="runtime/reobfuscate.py" />
  62 + <arg value="--client" />
  63 + <arg value="%*" />
  64 + </exec>
  65 + </target>
  66 +
  67 + <target name="savemd5" description="Put post-obfuscation MD5 to stored md5 set" if="outmd5set">
  68 + <echo level="info" message="Storing obfuscated MD5s" />
  69 +
  70 + <copy file="${temp}/client_reobf.md5" tofile="${md5.dir}/client_${outmd5set}.md5" overwrite="true" verbose="true" />
  71 + </target>
  72 +</project>
0 73 \ No newline at end of file
... ...
java/com/mumfrey/liteloader/debug/AuthenticationRequest.java 0 โ†’ 100644
  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 +
... ...
java/com/mumfrey/liteloader/debug/Start.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.debug;
  2 +import java.io.File;
  3 +import java.io.IOException;
  4 +import java.net.Proxy;
  5 +import java.net.URL;
  6 +
  7 +import net.minecraft.hopper.Util;
  8 +import net.minecraft.launcher.authentication.yggdrasil.AuthenticationResponse;
  9 +import net.minecraft.launchwrapper.Launch;
  10 +
  11 +import org.apache.commons.lang3.StringUtils;
  12 +
  13 +import com.google.gson.Gson;
  14 +import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
  15 +
  16 +/**
  17 + * Wrapper class for LaunchWrapper Main class, which logs into minecraft.net first so that online shizzle can be tested
  18 + *
  19 + * @author Adam Mummery-Smith
  20 + * @version 0.5
  21 + */
  22 +public abstract class Start
  23 +{
  24 + /**
  25 + * Username specified on the command line
  26 + */
  27 + private static String userName = "";
  28 +
  29 + /**
  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
  36 + *
  37 + * @param args
  38 + */
  39 + public static void main(String[] args)
  40 + {
  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 + }
  60 +
  61 + Start.showMessage(String.format("Launching game as %s", userName));
  62 +
  63 + File gameDir = new File(System.getProperty("user.dir"));
  64 + File assetsDir = new File(gameDir, "assets");
  65 +
  66 + args = new String[] {
  67 + "--tweakClass", LiteLoaderTweaker.class.getName(),
  68 + "--username", userName,
  69 + "--session", sessionId,
  70 + "--version", "mcp",
  71 + "--gameDir", gameDir.getAbsolutePath(),
  72 + "--assetsDir", assetsDir.getAbsolutePath()
  73 + };
  74 +
  75 + Launch.main(args);
  76 + }
  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 +}
... ...
lib/launcher.jar 0 โ†’ 100644
No preview for this file type
run/minecraft.key renamed to res/minecraft.key
No preview for this file type
run/com/mumfrey/liteloader/debug/Start.java deleted 100644 โ†’ 0
1   -package com.mumfrey.liteloader.debug;
2   -import java.io.BufferedReader;
3   -import java.io.DataInputStream;
4   -import java.io.DataOutputStream;
5   -import java.io.File;
6   -import java.io.IOException;
7   -import java.io.InputStreamReader;
8   -import java.io.UnsupportedEncodingException;
9   -import java.net.URL;
10   -import java.net.URLEncoder;
11   -import java.security.PublicKey;
12   -import java.security.cert.Certificate;
13   -
14   -import javax.net.ssl.HttpsURLConnection;
15   -
16   -import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
17   -
18   -import net.minecraft.launchwrapper.Launch;
19   -
20   -/**
21   - * Wrapper class for LaunchWrapper Main class, which logs into minecraft.net first so that online shizzle can be tested
22   - *
23   - * @author Adam Mummery-Smith
24   - * @version 0.4
25   - */
26   -public abstract class Start
27   -{
28   - /**
29   - * Username specified on the command line
30   - */
31   - public static String userName = "";
32   -
33   - /**
34   - * Latest minecraft version as recieved from minecraft.net
35   - */
36   - public static String latestVersion = "";
37   -
38   - /**
39   - * Download ticket issued to us by minecraft.net
40   - */
41   - public static String downloadTicket = "";
42   -
43   - /**
44   - * Session ID retrieved during login ("-" means no session, eg. offline)
45   - */
46   - public static String sessionId = "-";
47   -
48   - /**
49   - * Encoded certificate data in case the user forgets to extract minecraft.key !
50   - */
51   - private static int[] certificateData = {
52   - 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
53   - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc6, 0xf3, 0xde,
54   - 0xfd, 0xef, 0xa9, 0x62, 0x9c, 0xe0, 0x51, 0x28, 0x9b, 0xfb, 0x46, 0xbc, 0xf4, 0x1a, 0x03, 0x0d, 0x6f, 0x69,
55   - 0xf1, 0x98, 0x2a, 0xa6, 0x35, 0xb9, 0x62, 0xd6, 0x36, 0x6b, 0x64, 0x53, 0x87, 0x93, 0xd6, 0xa9, 0xd3, 0x46,
56   - 0xd7, 0x93, 0x4f, 0x1d, 0x8e, 0x50, 0x50, 0x7d, 0x51, 0x80, 0xd1, 0x29, 0x8f, 0x83, 0x37, 0xb6, 0x67, 0xfd,
57   - 0xde, 0xa3, 0xdf, 0x02, 0xda, 0x52, 0xba, 0x1c, 0x3a, 0x3e, 0x6f, 0xe4, 0xb6, 0xc8, 0x55, 0x75, 0x91, 0xf8,
58   - 0x6b, 0x2a, 0x51, 0x5a, 0xad, 0xf6, 0x26, 0x9b, 0xff, 0xcf, 0x67, 0x15, 0xa0, 0xb9, 0x5a, 0xb8, 0xca, 0xaf,
59   - 0x8f, 0xef, 0x9a, 0x15, 0x45, 0x9f, 0x87, 0xd0, 0x82, 0x89, 0x55, 0x45, 0x91, 0x7e, 0x90, 0x03, 0x84, 0x45,
60   - 0x6b, 0xdf, 0xeb, 0xa4, 0x95, 0x71, 0x74, 0xbd, 0x0f, 0x8b, 0xf7, 0xa8, 0xc4, 0xfa, 0xd5, 0x7d, 0x6f, 0xff,
61   - 0x01, 0xc0, 0x4a, 0x64, 0xd2, 0x73, 0x02, 0xf1, 0x4f, 0x72, 0x87, 0x48, 0x80, 0xa2, 0x0c, 0x9c, 0x3c, 0xd5,
62   - 0xad, 0xbe, 0xfb, 0xf0, 0x38, 0x34, 0xaf, 0x25, 0x10, 0xef, 0x96, 0xaf, 0x8c, 0x3d, 0xfa, 0x48, 0x54, 0x5f,
63   - 0xe4, 0x11, 0x43, 0xa2, 0x74, 0xe9, 0xc4, 0x28, 0xa9, 0x06, 0x3d, 0xcc, 0xbd, 0xc0, 0xbe, 0x48, 0xb4, 0x22,
64   - 0xd6, 0xd2, 0x34, 0xee, 0x2f, 0x07, 0x76, 0xe7, 0x33, 0x9f, 0x0d, 0xe5, 0x9e, 0x34, 0x8a, 0xc6, 0xec, 0x2b,
65   - 0x75, 0x15, 0x3a, 0x2f, 0xa8, 0xa6, 0x9a, 0x77, 0x68, 0x17, 0xf2, 0x90, 0x65, 0x5b, 0xef, 0x52, 0x33, 0xaa,
66   - 0x4b, 0x05, 0xf3, 0x08, 0x80, 0x0e, 0xdf, 0x0d, 0xfb, 0x8b, 0x67, 0x0e, 0x17, 0x54, 0x25, 0x9f, 0x75, 0xa9,
67   - 0xf8, 0x66, 0x28, 0xeb, 0x70, 0x31, 0x49, 0xac, 0xe3, 0x9d, 0xb1, 0x10, 0xc8, 0xfd, 0xfd, 0x8d, 0x23, 0x6c,
68   - 0xef, 0x02, 0x03, 0x01, 0x00, 0x01
69   - };
70   -
71   - /**
72   - * Entry point. Validates the parameters and performs the login
73   - *
74   - * @param args
75   - */
76   - public static void main(String[] args)
77   - {
78   - // Check we have enough arguments
79   - if (args.length < 2)
80   - {
81   - Start.showError("Invalid parameters specified for start, use: <username> <password> to log in to minecraft.net");
82   - userName = args.length < 1 ? System.getProperty("user.name") : args[0];
83   - }
84   - else
85   - {
86   - // Assign username as the first argument
87   - userName = args[0];
88   -
89   - // Perform the login if the second parameter is not "-" (indicating offline)
90   - if (!args[1].equals("-") && login(args[0], args[1], 13, true))
91   - {
92   - Start.showMessage(String.format("Successfully logged in as %s with session ID %s", userName, sessionId));
93   - args[0] = userName;
94   - args[1] = sessionId;
95   - }
96   - }
97   -
98   - Start.showMessage(String.format("Launching game as %s", userName));
99   -
100   - File gameDir = new File(System.getProperty("user.dir"));
101   - File assetsDir = new File(gameDir, "assets");
102   -
103   - args = new String[] {
104   - "--tweakClass", LiteLoaderTweaker.class.getName(),
105   - "--username", userName,
106   - "--session", sessionId,
107   - "--version", "mcp",
108   - "--gameDir", gameDir.getAbsolutePath(),
109   - "--assetsDir", assetsDir.getAbsolutePath()
110   - };
111   -
112   - Launch.main(args);
113   - }
114   -
115   - /**
116   - * Do login to minecraft.net. Based on the login method in the Launcher
117   - *
118   - * @param user Username
119   - * @param password Password
120   - * @param masqueradeLauncher Version Launcher version to masquerade as
121   - * @param validateCertificate True to validate the minecraft.net certificate. False if you can't be bothered or don't care :)
122   - * @return True if the login succeeded
123   - */
124   - private static boolean login(String user, String password, int masqueradeLauncherVersion, boolean validateCertificate)
125   - {
126   - try
127   - {
128   - String parameters = String.format("user=%s&password=%s&version=%s",URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(password, "UTF-8"), masqueradeLauncherVersion);
129   -
130   - Start.showMessage("Attempting to login to minecraft.net...");
131   - String result = excutePost("https://login.minecraft.net/", parameters, validateCertificate);
132   -
133   - if (result == null)
134   - {
135   - Start.showError("Can't connect to minecraft.net");
136   - return false;
137   - }
138   -
139   - if (!result.contains(":"))
140   - {
141   - Start.showError(result);
142   - return false;
143   - }
144   -
145   - try
146   - {
147   - String values[] = result.split(":");
148   -
149   - latestVersion = values[0].trim();
150   - downloadTicket = values[1].trim();
151   - userName = values[2].trim();
152   - sessionId = values[3].trim();
153   -
154   - return true;
155   - }
156   - catch(Exception e)
157   - {
158   - e.printStackTrace();
159   - return false;
160   - }
161   - }
162   - catch (UnsupportedEncodingException e)
163   - {
164   - Start.showError("Error encoding POST data, check your parameters");
165   - return false;
166   - }
167   - }
168   -
169   - /**
170   - * Execute a HTTPS POST. Based on code in the Minecraft launcher
171   - *
172   - * @param targetURL POST url
173   - * @param postData POST query string
174   - * @param validateCertificate True if the certificate should be validated against the local cache
175   - * @return Response data or null if the query fails
176   - */
177   - private static String excutePost(String targetURL, String postData, boolean validateCertificate)
178   - {
179   - HttpsURLConnection https = null;
180   - String responseData;
181   -
182   - try
183   - {
184   - URL url = new URL(targetURL);
185   -
186   - // Play that funky music white boy
187   - https = (HttpsURLConnection)url.openConnection();
188   - https.setRequestMethod("POST");
189   - https.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
190   - https.setRequestProperty("Content-Length", Integer.toString(postData.getBytes().length));
191   - https.setRequestProperty("Content-Language", "en-US");
192   - https.setUseCaches(false);
193   - https.setDoInput(true);
194   - https.setDoOutput(true);
195   - https.setConnectTimeout(1000);
196   - https.connect();
197   -
198   - // Validate the cert we received with the HTTPS response, if the user wants to
199   - if (validateCertificate)
200   - {
201   - Certificate certificates[] = https.getServerCertificates();
202   -
203   - byte bytes[] = new byte[294];
204   -
205   - try
206   - {
207   - DataInputStream keyReaderStream = new DataInputStream(Start.class.getResourceAsStream("/minecraft.key"));
208   - keyReaderStream.readFully(bytes);
209   - keyReaderStream.close();
210   - }
211   - catch (NullPointerException ex)
212   - {
213   - // Error loading from the key file (probably the user forgot to put minecraft.key in the bin folder)
214   - Start.showError("Missing minecraft.key, reverting to internal cache");
215   -
216   - for (int certIndex = 0; certIndex < 294; certIndex++)
217   - bytes[certIndex] = (byte)(certificateData[certIndex] & 0xFF);
218   - }
219   -
220   - PublicKey publicKey = certificates[0].getPublicKey();
221   - byte data[] = publicKey.getEncoded();
222   -
223   - for (int i = 0; i < data.length; i++)
224   - {
225   - if(data[i] != bytes[i])
226   - {
227   - Start.showError("Public key mismatch on " + targetURL);
228   - return null;
229   - }
230   - }
231   -
232   - Start.showMessage("Certificate validated ok for " + targetURL);
233   - }
234   -
235   - // Write ze postdata to ze server
236   - DataOutputStream postDataStream = new DataOutputStream(https.getOutputStream());
237   - postDataStream.writeBytes(postData);
238   - postDataStream.flush();
239   - postDataStream.close();
240   -
241   - // Get and concat the response
242   - BufferedReader reader = new BufferedReader(new InputStreamReader(https.getInputStream()));
243   - StringBuffer responseBuffer = new StringBuffer();
244   -
245   - String readLine;
246   - while((readLine = reader.readLine()) != null)
247   - {
248   - responseBuffer.append(readLine);
249   - responseBuffer.append('\r');
250   - }
251   -
252   - reader.close();
253   - responseData = responseBuffer.toString();
254   -
255   - https.disconnect();
256   - https = null;
257   - }
258   - catch (IOException e)
259   - {
260   - e.printStackTrace();
261   -
262   - if(https != null)
263   - https.disconnect();
264   -
265   - return null;
266   - }
267   - finally
268   - {
269   - if(https != null)
270   - {
271   - https.disconnect();
272   - }
273   - }
274   -
275   - return responseData;
276   - }
277   -
278   - /**
279   - * Show a message on stdout
280   - *
281   - * @param message
282   - */
283   - private static void showMessage(String message)
284   - {
285   - System.out.println("[START] [INFO] " + message);
286   - }
287   -
288   - /**
289   - * Show a message on stderr
290   - *
291   - * @param message
292   - */
293   - private static void showError(String message)
294   - {
295   - System.err.println("[START] [ERROR] " + message);
296   - }
297   -}