summaryrefslogtreecommitdiff
path: root/src/net/minecraft
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/minecraft')
-rw-r--r--src/net/minecraft/GameUpdater.java205
1 files changed, 107 insertions, 98 deletions
diff --git a/src/net/minecraft/GameUpdater.java b/src/net/minecraft/GameUpdater.java
index be2f532..9a79880 100644
--- a/src/net/minecraft/GameUpdater.java
+++ b/src/net/minecraft/GameUpdater.java
@@ -1,21 +1,42 @@
package net.minecraft;
import java.applet.Applet;
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.net.*;
-import java.security.*;
-import java.security.cert.Certificate;
+import java.net.HttpURLConnection;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
import java.util.Enumeration;
-import java.util.StringTokenizer;
import java.util.Vector;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
-
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
public class GameUpdater implements Runnable {
public static final int STATE_INIT = 1;
@@ -61,7 +82,7 @@ public class GameUpdater implements Runnable {
}
public void init() {
- this.state = 1;
+ this.state = STATE_INIT;
try {
Class.forName("LZMA.LzmaInputStream");
@@ -88,25 +109,25 @@ public class GameUpdater implements Runnable {
protected String getDescriptionForState() {
switch (this.state) {
- case 1:
+ case STATE_INIT:
return "Initializing loader";
- case 2:
+ case STATE_DETERMINING_PACKAGES:
return "Determining packages to load";
- case 3:
+ case STATE_CHECKING_CACHE:
return "Checking cache for existing files";
- case 4:
+ case STATE_DOWNLOADING:
return "Downloading packages";
- case 5:
+ case STATE_EXTRACTING_PACKAGES:
return "Extracting downloaded packages";
- case 6:
+ case STATE_UPDATING_CLASSPATH:
return "Updating classpath";
- case 7:
+ case STATE_SWITCHING_APPLET:
return "Switching applet";
- case 8:
+ case STATE_INITIALIZE_REAL_APPLET:
return "Initializing real applet";
- case 9:
+ case STATE_START_REAL_APPLET:
return "Starting real applet";
- case 10:
+ case STATE_DONE:
return "Done loading";
}
return "unknown state";
@@ -125,49 +146,47 @@ public class GameUpdater implements Runnable {
}
protected void loadJarURLs() throws Exception {
- this.state = 2;
- String jarList = "lwjgl.jar, jinput.jar, lwjgl_util.jar, " + this.mainGameUrl;
- jarList = trimExtensionByCapabilities(jarList);
-
- StringTokenizer jar = new StringTokenizer(jarList, ", ");
- int jarCount = jar.countTokens() + 1;
-
- this.urlList = new URL[jarCount];
+ this.state = STATE_DETERMINING_PACKAGES;
- URL path = new URL("http://s3.amazonaws.com/MinecraftDownload/");
-
- for (int i = 0; i < jarCount - 1; i++) {
- this.urlList[i] = new URL(path, jar.nextToken());
- }
+ URL path = new URL("http://files.betacraft.uk/launcher/assets/");
+ this.urlList = new URL[3];
String osName = System.getProperty("os.name");
- String nativeJar = null;
+ String librariesZip = "libs.zip";
+ String nativesZip = null;
if (osName.startsWith("Win")) {
- nativeJar = "windows_natives.jar.lzma";
+ librariesZip = "libs-windows.zip";
+ nativesZip = "natives-windows.zip";
} else if (osName.startsWith("Linux")) {
- nativeJar = "linux_natives.jar.lzma";
+ librariesZip = "libs-linux.zip";
+ nativesZip = "natives-linux.zip";
} else if (osName.startsWith("Mac")) {
- nativeJar = "macosx_natives.jar.lzma";
- } else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
- nativeJar = "solaris_natives.jar.lzma";
+ librariesZip = "libs-osx.zip";
+ nativesZip = "natives-osx.zip";
} else {
fatalErrorOccured("OS (" + osName + ") not supported", null);
+ return;
}
- if (nativeJar == null) {
+ if (nativesZip == null) {
fatalErrorOccured("no lwjgl natives files found", null);
} else {
- nativeJar = trimExtensionByCapabilities(nativeJar);
- this.urlList[jarCount - 1] = new URL(path, nativeJar);
+ this.urlList[0] = new URL(path, nativesZip);
}
+
+ this.urlList[1] = new URL(path, librariesZip);
+
+ // TODO: BetaCraft's server only has versions missing from mojang's download site.
+ // The launcher should use the info in "jsons.zip" to get the URL for the jar download.
+ this.urlList[2] = new URL(path, "versions/a1.0.13.jar");
}
public void run() {
init();
- this.state = 3;
+ this.state = STATE_CHECKING_CACHE;
this.percentage = 5;
try {
@@ -209,7 +228,7 @@ public class GameUpdater implements Runnable {
}
updateClassPath(dir);
- this.state = 10;
+ this.state = STATE_DONE;
} catch (AccessControlException ace) {
fatalErrorOccured(ace.getMessage(), ace);
this.certificateRefused = true;
@@ -235,13 +254,14 @@ public class GameUpdater implements Runnable {
protected void updateClassPath(File dir) throws Exception {
- this.state = 6;
+ this.state = STATE_UPDATING_CLASSPATH;
this.percentage = 95;
- URL[] urls = new URL[this.urlList.length];
- for (int i = 0; i < this.urlList.length; i++) {
- urls[i] = (new File(dir, getJarName(this.urlList[i]))).toURI().toURL();
+ File[] files = dir.listFiles((dir1, name) -> name.endsWith(".jar"));
+ URL[] urls = new URL[files.length];
+ for (int i = 0; i < files.length; i++) {
+ urls[i] = files[i].toURI().toURL();
}
if (classLoader == null) {
@@ -318,8 +338,7 @@ public class GameUpdater implements Runnable {
protected void downloadJars(String path) throws Exception {
- this.state = 4;
-
+ this.state = STATE_DOWNLOADING;
int[] fileSizes = new int[this.urlList.length];
@@ -511,9 +530,28 @@ public class GameUpdater implements Runnable {
f.delete();
}
+ protected void extractZIP(String in, String out) throws Exception {
+ File originalFile = new File(in);
+ Path targetDir = originalFile.toPath().getParent();
+ ZipInputStream zipStream = new ZipInputStream(Files.newInputStream(originalFile.toPath()));
+
+ ZipEntry entry;
+ while ((entry = zipStream.getNextEntry()) != null) {
+ Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
+ if (!resolvedPath.startsWith(targetDir)) {
+ throw new RuntimeException("Entry with illegal path: " + entry.getName());
+ }
+ if (entry.isDirectory()) {
+ Files.createDirectories(resolvedPath);
+ } else {
+ Files.createDirectories(resolvedPath.getParent());
+ Files.copy(zipStream, resolvedPath);
+ }
+ }
+ }
protected void extractJars(String path) throws Exception {
- this.state = 5;
+ this.state = STATE_EXTRACTING_PACKAGES;
float increment = 10.0F / this.urlList.length;
@@ -533,20 +571,23 @@ public class GameUpdater implements Runnable {
} else if (filename.endsWith(".lzma")) {
this.subtaskMessage = "Extracting: " + filename + " to " + filename.replace(".lzma", "");
extractLZMA(path + filename, path + filename.replace(".lzma", ""));
+ } else if (filename.endsWith(".zip")) {
+ this.subtaskMessage = "Extracting: " + filename + " to " + filename.replace(".zip", "");
+ // TODO: This should only operate on the libraries zip
+ extractZIP(path + filename, path + filename.replace(".zip", ""));
}
}
}
protected void extractNatives(String path) throws Exception {
- this.state = 5;
-
+ this.state = STATE_EXTRACTING_PACKAGES;
int initialPercentage = this.percentage;
- String nativeJar = getJarName(this.urlList[this.urlList.length - 1]);
+ String nativeJar = getJarName(this.urlList[0]);
+ /* TODO: There should still be some kind of validation probably
Certificate[] certificate = Launcher.class.getProtectionDomain().getCodeSource().getCertificates();
-
if (certificate == null) {
URL location = Launcher.class.getProtectionDomain().getCodeSource().getLocation();
@@ -557,50 +598,38 @@ public class GameUpdater implements Runnable {
} catch (Exception exception) {
}
}
-
+ */
File nativeFolder = new File(path + "natives");
if (!nativeFolder.exists()) {
nativeFolder.mkdir();
}
- JarFile jarFile = new JarFile(path + nativeJar, true);
- Enumeration<JarEntry> entities = jarFile.entries();
+ ZipFile zipFile = new ZipFile(path + nativeJar);
+ Enumeration<? extends ZipEntry> entities = zipFile.entries();
this.totalSizeExtract = 0;
-
-
while (entities.hasMoreElements()) {
- JarEntry entry = entities.nextElement();
-
-
- if (entry.isDirectory() || entry.getName().indexOf('/') != -1) {
+ ZipEntry entry = entities.nextElement();
+ if (entry.isDirectory() || entry.getName().indexOf('/') != -1)
continue;
- }
this.totalSizeExtract = (int) (this.totalSizeExtract + entry.getSize());
}
this.currentSizeExtract = 0;
-
- entities = jarFile.entries();
-
+ entities = zipFile.entries();
while (entities.hasMoreElements()) {
- JarEntry entry = entities.nextElement();
+ ZipEntry entry = entities.nextElement();
- if (entry.isDirectory() || entry.getName().indexOf('/') != -1) {
+ if (entry.isDirectory() || entry.getName().indexOf('/') != -1)
continue;
- }
File file = new File(path + "natives" + File.separator + entry.getName());
- if (file.exists() &&
- !file.delete()) {
+ if (file.exists() && !file.delete())
continue;
- }
-
-
- InputStream in = jarFile.getInputStream(jarFile.getEntry(entry.getName()));
- OutputStream out = new FileOutputStream(path + "natives" + File.separator + entry.getName());
+ InputStream in = zipFile.getInputStream(zipFile.getEntry(entry.getName()));
+ OutputStream out = Files.newOutputStream(Paths.get(nativeFolder.getPath(), entry.getName()));
byte[] buffer = new byte[65536];
int bufferSize;
@@ -612,36 +641,17 @@ public class GameUpdater implements Runnable {
this.subtaskMessage = "Extracting: " + entry.getName() + " " + (this.currentSizeExtract * 100 / this.totalSizeExtract) + "%";
}
- validateCertificateChain(certificate, entry.getCertificates());
-
in.close();
out.close();
}
this.subtaskMessage = "";
- jarFile.close();
+ zipFile.close();
File f = new File(path + nativeJar);
f.delete();
}
-
- protected static void validateCertificateChain(Certificate[] ownCerts, Certificate[] native_certs) throws Exception {
- if (ownCerts == null)
- return;
- if (native_certs == null)
- throw new Exception("Unable to validate certificate chain. Native entry did not have a certificate chain at all");
-
- if (ownCerts.length != native_certs.length)
- throw new Exception("Unable to validate certificate chain. Chain differs in length [" + ownCerts.length + " vs " + native_certs.length + "]");
-
- for (int i = 0; i < ownCerts.length; i++) {
- if (!ownCerts[i].equals(native_certs[i])) {
- throw new Exception("Certificate mismatch: " + ownCerts[i] + " != " + native_certs[i]);
- }
- }
- }
-
protected String getJarName(URL url) {
String fileName = url.getFile();
@@ -677,7 +687,6 @@ public class GameUpdater implements Runnable {
}
}
-
public boolean canPlayOffline() {
try {
String path = AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {