better jar handling; get native files from manifest instead of iterator over every file in the jar
This commit is contained in:
@@ -19,33 +19,18 @@
|
||||
package itdelatrisu.opsu;
|
||||
|
||||
import org.newdawn.slick.util.Log;
|
||||
import yugecin.opsudance.utils.ManifestWrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import static yugecin.opsudance.core.InstanceContainer.*;
|
||||
|
||||
/**
|
||||
* Native loader, based on the JarSplice launcher.
|
||||
*
|
||||
* @author http://ninjacave.com
|
||||
*/
|
||||
public class NativeLoader {
|
||||
|
||||
public static void loadNatives() {
|
||||
try {
|
||||
unpackNatives();
|
||||
} catch (IOException e) {
|
||||
String msg = String.format("Could not unpack native(s): %s", e.getMessage());
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
|
||||
public static void setNativePath() {
|
||||
String nativepath = config.NATIVE_DIR.getAbsolutePath();
|
||||
System.setProperty("org.lwjgl.librarypath", nativepath);
|
||||
System.setProperty("java.library.path", nativepath);
|
||||
@@ -65,62 +50,43 @@ public class NativeLoader {
|
||||
* Unpacks natives for the current operating system to the natives directory.
|
||||
* @throws IOException if an I/O exception occurs
|
||||
*/
|
||||
public static void unpackNatives() throws IOException {
|
||||
if (env.jarfile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static void loadNatives(JarFile jarfile, ManifestWrapper manifest) throws IOException {
|
||||
if (!config.NATIVE_DIR.exists() && !config.NATIVE_DIR.mkdir()) {
|
||||
String msg = String.format("Could not create folder '%s'",
|
||||
config.NATIVE_DIR.getAbsolutePath());
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
|
||||
Enumeration<JarEntry> entries = env.jarfile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry e = entries.nextElement();
|
||||
if (e == null)
|
||||
break;
|
||||
|
||||
File f = new File(config.NATIVE_DIR, e.getName());
|
||||
if (isNativeFile(e.getName()) && !e.isDirectory() && e.getName().indexOf('/') == -1 && !f.exists()) {
|
||||
InputStream in = env.jarfile.getInputStream(env.jarfile.getEntry(e.getName()));
|
||||
OutputStream out = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[65536];
|
||||
int bufferSize;
|
||||
while ((bufferSize = in.read(buffer, 0, buffer.length)) != -1)
|
||||
out.write(buffer, 0, bufferSize);
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
env.jarfile.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given file name is a native file for the current operating system.
|
||||
* @param entryName the file name
|
||||
* @return true if the file is a native that should be loaded, false otherwise
|
||||
*/
|
||||
private static boolean isNativeFile(String entryName) {
|
||||
String osName = System.getProperty("os.name");
|
||||
String name = entryName.toLowerCase();
|
||||
|
||||
String nativekey = null;
|
||||
if (osName.startsWith("Win")) {
|
||||
if (name.endsWith(".dll"))
|
||||
return true;
|
||||
nativekey = "WinNatives";
|
||||
} else if (osName.startsWith("Linux")) {
|
||||
if (name.endsWith(".so"))
|
||||
return true;
|
||||
nativekey = "NixNatives";
|
||||
} else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
|
||||
if (name.endsWith(".dylib") || name.endsWith(".jnilib"))
|
||||
return true;
|
||||
nativekey = "MacNatives";
|
||||
}
|
||||
|
||||
if (nativekey == null) {
|
||||
Log.warn("Cannot determine natives for os " + osName);
|
||||
return;
|
||||
}
|
||||
|
||||
String natives = manifest.valueOrDefault(null, nativekey, null);
|
||||
if (natives == null) {
|
||||
String msg = String.format("No entry for '%s' in manifest, jar is badly packed or damaged",
|
||||
nativekey);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
String[] nativefiles = natives.split(",");
|
||||
for (String nativefile : nativefiles) {
|
||||
File unpackedFile = new File(config.NATIVE_DIR, nativefile);
|
||||
if (unpackedFile.exists()) {
|
||||
continue;
|
||||
}
|
||||
Utils.unpackFromJar(jarfile, unpackedFile, nativefile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,14 +21,7 @@ package itdelatrisu.opsu;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import itdelatrisu.opsu.downloads.Download;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
@@ -37,6 +30,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -53,6 +47,7 @@ import org.newdawn.slick.util.Log;
|
||||
|
||||
import com.sun.jna.platform.FileUtils;
|
||||
import yugecin.opsudance.core.DisplayContainer;
|
||||
import yugecin.opsudance.core.NotNull;
|
||||
import yugecin.opsudance.core.errorhandling.ErrorHandler;
|
||||
|
||||
import static yugecin.opsudance.core.InstanceContainer.*;
|
||||
@@ -537,4 +532,19 @@ public class Utils {
|
||||
key != Keyboard.KEY_F7 && key != Keyboard.KEY_F10 && key != Keyboard.KEY_F12);
|
||||
}
|
||||
|
||||
public static void unpackFromJar(@NotNull JarFile jarfile, @NotNull File unpackedFile,
|
||||
@NotNull String filename) throws IOException {
|
||||
InputStream in = jarfile.getInputStream(jarfile.getEntry(filename));
|
||||
OutputStream out = new FileOutputStream(unpackedFile);
|
||||
|
||||
byte[] buffer = new byte[65536];
|
||||
int bufferSize;
|
||||
while ((bufferSize = in.read(buffer, 0, buffer.length)) != -1) {
|
||||
out.write(buffer, 0, bufferSize);
|
||||
}
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user