Merge pull request #60 from TheBiblMan/master
faster loading. (please fix this fucking code, it's too bad) -Bibl
This commit is contained in:
commit
fbd4d341aa
21 changed files with 1498 additions and 404 deletions
198
src/the/bytecode/club/bootloader/Boot.java
Normal file
198
src/the/bytecode/club/bootloader/Boot.java
Normal file
|
@ -0,0 +1,198 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import me.konloch.kontainer.io.HTTPRequest;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 03:22:37
|
||||
*/
|
||||
public class Boot {
|
||||
|
||||
private static InitialBootScreen screen;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ILoader loader = findLoader();
|
||||
|
||||
screen = new InitialBootScreen();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
screen.setVisible(true);
|
||||
}
|
||||
});
|
||||
create(loader, args.length > 0 ? Boolean.valueOf(args[0]) : true);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
screen.setVisible(false);
|
||||
}
|
||||
});
|
||||
Class<?> klass = loader.loadClass("the.bytecode.club.bytecodeviewer.BytecodeViewer");
|
||||
klass.getDeclaredMethod("main", new Class<?>[] { String[].class }).invoke(null, new Object[] { args });
|
||||
}
|
||||
|
||||
private static void create(ILoader loader, boolean clean) throws Exception {
|
||||
setState("Bytecode Viewer Boot Screen - Checking Libraries...");
|
||||
|
||||
final File libsDirectory = libsDir();
|
||||
|
||||
List<String> urlList = new ArrayList<String>();
|
||||
HTTPRequest req = new HTTPRequest(new URL("https://github.com/Konloch/bytecode-viewer/tree/master/libs"));
|
||||
for (String s : req.read())
|
||||
if (s.contains("href=\"/Konloch/bytecode-viewer/blob/master/libs/")) {
|
||||
urlList.add("https://github.com" + s.split("<a href=")[1].split("\"")[1]);
|
||||
}
|
||||
|
||||
if (urlList.isEmpty()) {
|
||||
JOptionPane
|
||||
.showMessageDialog(
|
||||
null,
|
||||
"Bytecode Viewer ran into an issue, for some reason github is not returning what we're expecting. Please try rebooting, if this issue persists please contact @Konloch.",
|
||||
"Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clean)
|
||||
libsDirectory.delete();
|
||||
|
||||
if (!libsDirectory.exists())
|
||||
libsDirectory.mkdir();
|
||||
|
||||
List<String> libsList = new ArrayList<String>();
|
||||
List<String> libsFileList = new ArrayList<String>();
|
||||
for (File f : libsDirectory.listFiles()) {
|
||||
libsList.add(f.getName());
|
||||
libsFileList.add(f.getAbsolutePath());
|
||||
}
|
||||
|
||||
screen.getProgressBar().setMaximum(urlList.size() * 2);
|
||||
|
||||
int completedCheck = 0;
|
||||
|
||||
for (String s : urlList) {
|
||||
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length(), s.length());
|
||||
if (!libsList.contains(fileName)) {
|
||||
setState("Bytecode Viewer Boot Screen - Downloading " + fileName);
|
||||
System.out.println("Downloading " + fileName);
|
||||
boolean passed = false;
|
||||
while (!passed) {
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName).openConnection().getInputStream();
|
||||
fos = new FileOutputStream(new File(libsDirectory, fileName));
|
||||
System.out.println("Downloading from " + s);
|
||||
byte[] buffer = new byte[8192];
|
||||
int len;
|
||||
int downloaded = 0;
|
||||
boolean flag = false;
|
||||
while ((len = is.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
fos.flush();
|
||||
downloaded += 8192;
|
||||
int mbs = downloaded / 1048576;
|
||||
if (mbs % 5 == 0 && mbs != 0) {
|
||||
if (!flag)
|
||||
System.out.println("Downloaded " + mbs + "MBs so far");
|
||||
flag = true;
|
||||
} else
|
||||
flag = false;
|
||||
}
|
||||
libsFileList.add(new File(libsDirectory, fileName).getAbsolutePath());
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
fos.flush();
|
||||
}
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Download finished!");
|
||||
passed = true;
|
||||
}
|
||||
}
|
||||
|
||||
completedCheck++;
|
||||
screen.getProgressBar().setValue(completedCheck);
|
||||
}
|
||||
|
||||
setState("Bytecode Viewer Boot Screen - Checking & Deleting Foreign/Outdated Libraries...");
|
||||
System.out.println("Checking & Deleting foreign/outdated libraries");
|
||||
for (String s : libsFileList) {
|
||||
File f = new File(s);
|
||||
boolean delete = true;
|
||||
for (String urlS : urlList) {
|
||||
String fileName = urlS.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length(), urlS.length());
|
||||
if (fileName.equals(f.getName()))
|
||||
delete = false;
|
||||
}
|
||||
if (delete) {
|
||||
f.delete();
|
||||
System.out.println("Detected & Deleted Foriegn/Outdated Jar/File: " + f.getName());
|
||||
}
|
||||
}
|
||||
|
||||
setState("Bytecode Viewer Boot Screen - Loading Libraries...");
|
||||
System.out.println("Loading libraries...");
|
||||
|
||||
for (String s : libsFileList) {
|
||||
if (s.endsWith(".jar")) {
|
||||
File f = new File(s);
|
||||
if (f.exists()) {
|
||||
setState("Bytecode Viewer Boot Screen - Loading Library " + f.getName());
|
||||
System.out.println("Loading library " + f.getName());
|
||||
|
||||
try {
|
||||
JarInfo jar = new JarInfo(f);
|
||||
ExternalLibrary lib = new ExternalLibrary(jar);
|
||||
loader.bind(lib);
|
||||
System.out.println("Succesfully loaded " + f.getName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
f.delete();
|
||||
JOptionPane.showMessageDialog(null, "Error, Library " + f.getName() + " is corrupt, please restart to redownload it.",
|
||||
"Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
completedCheck++;
|
||||
screen.getProgressBar().setValue(completedCheck);
|
||||
}
|
||||
}
|
||||
|
||||
setState("Bytecode Viewer Boot Screen - Booting!");
|
||||
}
|
||||
|
||||
private static File libsDir() {
|
||||
File dir = new File(System.getProperty("user.home"), ".Bytecode-Viewer");
|
||||
while (!dir.exists())
|
||||
dir.mkdirs();
|
||||
|
||||
return new File(dir, "libs");
|
||||
}
|
||||
|
||||
private static void setState(String s) {
|
||||
screen.setTitle(s);
|
||||
}
|
||||
|
||||
private static ILoader findLoader() {
|
||||
// TODO: Find from providers
|
||||
return new LibraryClassLoader();
|
||||
}
|
||||
}
|
35
src/the/bytecode/club/bootloader/ClassHelper.java
Normal file
35
src/the/bytecode/club/bootloader/ClassHelper.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 25 May 2015 (actually before this)
|
||||
*/
|
||||
public class ClassHelper {
|
||||
|
||||
public static Map<String, ClassNode> convertToMap(Collection<ClassNode> classes) {
|
||||
Map<String, ClassNode> map = new HashMap<String, ClassNode>();
|
||||
for (ClassNode cn : classes) {
|
||||
map.put(cn.name, cn);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <T, K> Map<T, K> copyOf(Map<T, K> src) {
|
||||
Map<T, K> dst = new HashMap<T, K>();
|
||||
copy(src, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
public static <T, K> void copy(Map<T, K> src, Map<T, K> dst) {
|
||||
for(Entry<T, K> e : src.entrySet()) {
|
||||
dst.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
207
src/the/bytecode/club/bootloader/ClassTree.java
Normal file
207
src/the/bytecode/club/bootloader/ClassTree.java
Normal file
|
@ -0,0 +1,207 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import static the.bytecode.club.bootloader.ClassHelper.convertToMap;
|
||||
import static the.bytecode.club.bootloader.ClassHelper.copyOf;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 25 May 2015 (actually before this)
|
||||
*/
|
||||
public class ClassTree {
|
||||
private static final SetCreator<ClassNode> SET_CREATOR = new SetCreator<ClassNode>();
|
||||
|
||||
private final Map<String, ClassNode> classes;
|
||||
private final NullPermeableHashMap<ClassNode, Set<ClassNode>> supers;
|
||||
private final NullPermeableHashMap<ClassNode, Set<ClassNode>> delgates;
|
||||
|
||||
public ClassTree() {
|
||||
classes = new HashMap<String, ClassNode>();
|
||||
supers = new NullPermeableHashMap<ClassNode, Set<ClassNode>>(SET_CREATOR);
|
||||
delgates = new NullPermeableHashMap<ClassNode, Set<ClassNode>>(SET_CREATOR);
|
||||
}
|
||||
|
||||
public ClassTree(Collection<ClassNode> classes) {
|
||||
this(convertToMap(classes));
|
||||
}
|
||||
|
||||
public ClassTree(Map<String, ClassNode> classes_) {
|
||||
classes = copyOf(classes_);
|
||||
supers = new NullPermeableHashMap<ClassNode, Set<ClassNode>>(SET_CREATOR);
|
||||
delgates = new NullPermeableHashMap<ClassNode, Set<ClassNode>>(SET_CREATOR);
|
||||
|
||||
build(classes);
|
||||
}
|
||||
|
||||
// TODO: optimise
|
||||
public void build(Map<String, ClassNode> classes) {
|
||||
for (ClassNode node : classes.values()) {
|
||||
for (String iface : node.interfaces) {
|
||||
ClassNode ifacecs = classes.get(iface);
|
||||
if (ifacecs == null)
|
||||
continue;
|
||||
|
||||
getDelegates0(ifacecs).add(node);
|
||||
|
||||
Set<ClassNode> superinterfaces = new HashSet<ClassNode>();
|
||||
buildSubTree(classes, superinterfaces, ifacecs);
|
||||
|
||||
getSupers0(node).addAll(superinterfaces);
|
||||
}
|
||||
ClassNode currentSuper = classes.get(node.superName);
|
||||
while (currentSuper != null) {
|
||||
getDelegates0(currentSuper).add(node);
|
||||
getSupers0(node).add(currentSuper);
|
||||
for (String iface : currentSuper.interfaces) {
|
||||
ClassNode ifacecs = classes.get(iface);
|
||||
if (ifacecs == null)
|
||||
continue;
|
||||
getDelegates0(ifacecs).add(currentSuper);
|
||||
Set<ClassNode> superinterfaces = new HashSet<ClassNode>();
|
||||
buildSubTree(classes, superinterfaces, ifacecs);
|
||||
getSupers0(currentSuper).addAll(superinterfaces);
|
||||
getSupers0(node).addAll(superinterfaces);
|
||||
}
|
||||
currentSuper = classes.get(currentSuper.superName);
|
||||
}
|
||||
|
||||
getSupers0(node);
|
||||
getDelegates0(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void build(ClassNode node) {
|
||||
for (String iface : node.interfaces) {
|
||||
ClassNode ifacecs = classes.get(iface);
|
||||
if (ifacecs == null)
|
||||
continue;
|
||||
|
||||
getDelegates0(ifacecs).add(node);
|
||||
|
||||
Set<ClassNode> superinterfaces = new HashSet<ClassNode>();
|
||||
buildSubTree(classes, superinterfaces, ifacecs);
|
||||
|
||||
getSupers0(node).addAll(superinterfaces);
|
||||
}
|
||||
ClassNode currentSuper = classes.get(node.superName);
|
||||
while (currentSuper != null) {
|
||||
getDelegates0(currentSuper).add(node);
|
||||
getSupers0(node).add(currentSuper);
|
||||
for (String iface : currentSuper.interfaces) {
|
||||
ClassNode ifacecs = classes.get(iface);
|
||||
if (ifacecs == null)
|
||||
continue;
|
||||
getDelegates0(ifacecs).add(currentSuper);
|
||||
Set<ClassNode> superinterfaces = new HashSet<ClassNode>();
|
||||
buildSubTree(classes, superinterfaces, ifacecs);
|
||||
getSupers0(currentSuper).addAll(superinterfaces);
|
||||
getSupers0(node).addAll(superinterfaces);
|
||||
}
|
||||
currentSuper = classes.get(currentSuper.superName);
|
||||
}
|
||||
|
||||
getSupers0(node);
|
||||
getDelegates0(node);
|
||||
|
||||
classes.put(node.name, node);
|
||||
}
|
||||
|
||||
private void buildSubTree(Map<String, ClassNode> classes, Collection<ClassNode> superinterfaces, ClassNode current) {
|
||||
superinterfaces.add(current);
|
||||
for (String iface : current.interfaces) {
|
||||
ClassNode cs = classes.get(iface);
|
||||
if(cs != null) {
|
||||
getDelegates0(cs).add(current);
|
||||
buildSubTree(classes, superinterfaces, cs);
|
||||
} else {
|
||||
// System.out.println("Null interface -> " + iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<MethodNode> getMethodsFromSuper(MethodNode m) {
|
||||
return getMethodsFromSuper(m.owner, m.name, m.desc);
|
||||
}
|
||||
|
||||
public Set<MethodNode> getMethodsFromSuper(ClassNode node, String name, String desc) {
|
||||
Set<MethodNode> methods = new HashSet<MethodNode>();
|
||||
for (ClassNode super_ : getSupers(node)) {
|
||||
for (MethodNode mn : super_.methods) {
|
||||
if (mn.name.equals(name) && mn.desc.equals(desc)) {
|
||||
methods.add(mn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
public Set<MethodNode> getMethodsFromDelegates(MethodNode m) {
|
||||
return getMethodsFromDelegates(m.owner, m.name, m.desc);
|
||||
}
|
||||
|
||||
public Set<MethodNode> getMethodsFromDelegates(ClassNode node, String name, String desc) {
|
||||
Set<MethodNode> methods = new HashSet<MethodNode>();
|
||||
for (ClassNode delegate : getDelegates(node)) {
|
||||
for (MethodNode mn : delegate.methods) {
|
||||
if (mn.name.equals(name) && mn.desc.equals(desc)) {
|
||||
methods.add(mn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
public MethodNode getFirstMethodFromSuper(ClassNode node, String name, String desc) {
|
||||
for (ClassNode super_ : getSupers(node)) {
|
||||
for (MethodNode mn : super_.methods) {
|
||||
if (mn.name.equals(name) && mn.desc.equals(desc)) {
|
||||
return mn;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClassNode getClass(String name) {
|
||||
return classes.get(name);
|
||||
}
|
||||
|
||||
public boolean isInherited(ClassNode cn, String name, String desc) {
|
||||
return getFirstMethodFromSuper(cn, name, desc) != null;
|
||||
}
|
||||
|
||||
public boolean isInherited(ClassNode first, MethodNode mn) {
|
||||
return mn.owner.name.equals(first.name) && isInherited(mn.owner, mn.name, mn.desc);
|
||||
}
|
||||
|
||||
private Set<ClassNode> getSupers0(ClassNode cn) {
|
||||
return supers.getNonNull(cn);
|
||||
}
|
||||
|
||||
private Set<ClassNode> getDelegates0(ClassNode cn) {
|
||||
return delgates.getNonNull(cn);
|
||||
}
|
||||
|
||||
public Map<String, ClassNode> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
public Set<ClassNode> getSupers(ClassNode cn) {
|
||||
return Collections.unmodifiableSet(supers.get(cn));
|
||||
// return supers.get(cn);
|
||||
}
|
||||
|
||||
public Set<ClassNode> getDelegates(ClassNode cn) {
|
||||
return Collections.unmodifiableSet(delgates.get(cn));
|
||||
// return delgates.get(cn);
|
||||
}
|
||||
}
|
28
src/the/bytecode/club/bootloader/DataContainer.java
Normal file
28
src/the/bytecode/club/bootloader/DataContainer.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public abstract class DataContainer<T> extends ArrayList<T> {
|
||||
|
||||
private static final long serialVersionUID = -9022506488647444546L;
|
||||
|
||||
public DataContainer() {
|
||||
this(16);
|
||||
}
|
||||
|
||||
public DataContainer(int cap) {
|
||||
super(cap);
|
||||
}
|
||||
|
||||
public DataContainer(Collection<T> data) {
|
||||
addAll(data);
|
||||
}
|
||||
|
||||
public abstract Map<String, T> namedMap();
|
||||
}
|
87
src/the/bytecode/club/bootloader/ExternalLibrary.java
Normal file
87
src/the/bytecode/club/bootloader/ExternalLibrary.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 02:33:23
|
||||
*/
|
||||
public class ExternalLibrary extends ExternalResource<JarContents<ClassNode>> {
|
||||
|
||||
/**
|
||||
* @param location
|
||||
*/
|
||||
public ExternalLibrary(URL location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jar
|
||||
*/
|
||||
public ExternalLibrary(JarInfo jar) {
|
||||
super(createJarURL(jar));
|
||||
}
|
||||
|
||||
public static URL createJarURL(JarInfo jar) {
|
||||
try {
|
||||
return jar.formattedURL();
|
||||
} catch(MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] read(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1)
|
||||
byteArrayOut.write(buffer, 0, bytesRead);
|
||||
byteArrayOut.close();
|
||||
return byteArrayOut.toByteArray();
|
||||
}
|
||||
|
||||
protected ClassNode create(byte[] b) {
|
||||
ClassReader cr = new ClassReader(b);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, 0);
|
||||
return cn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see the.bytecode.club.bytecodeviewer.loadermodel.ExternalResource#load()
|
||||
*/
|
||||
@Override
|
||||
public JarContents<ClassNode> load() throws IOException {
|
||||
JarContents<ClassNode> contents = new JarContents<ClassNode>();
|
||||
|
||||
JarURLConnection con = (JarURLConnection) getLocation().openConnection();
|
||||
JarFile jar = con.getJarFile();
|
||||
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
byte[] bytes = read(jar.getInputStream(entry));
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
ClassNode cn = create(bytes);
|
||||
contents.getClassContents().add(cn);
|
||||
} else {
|
||||
JarResource resource = new JarResource(entry.getName(), bytes);
|
||||
contents.getResourceContents().add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
return contents;
|
||||
}
|
||||
}
|
55
src/the/bytecode/club/bootloader/ExternalResource.java
Normal file
55
src/the/bytecode/club/bootloader/ExternalResource.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 02:30:30
|
||||
*/
|
||||
public abstract class ExternalResource<T> {
|
||||
|
||||
private final URL location;
|
||||
|
||||
public ExternalResource(URL location) {
|
||||
if(location == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public URL getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public abstract T load() throws IOException;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((location == null) ? 0 : location.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ExternalResource<?> other = (ExternalResource<?>) obj;
|
||||
if (location == null) {
|
||||
if (other.location != null)
|
||||
return false;
|
||||
} else if (!location.equals(other.location))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Library @" + location.toExternalForm();
|
||||
}
|
||||
}
|
16
src/the/bytecode/club/bootloader/ILoader.java
Normal file
16
src/the/bytecode/club/bootloader/ILoader.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 02:29:43
|
||||
*/
|
||||
public abstract interface ILoader {
|
||||
|
||||
public abstract void bind(ExternalResource<JarContents<ClassNode>> resource);
|
||||
|
||||
abstract Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError;
|
||||
|
||||
public abstract Class<?> loadClass(String name) throws ClassNotFoundException, NoClassDefFoundError;
|
||||
}
|
85
src/the/bytecode/club/bootloader/InitialBootScreen.java
Normal file
85
src/the/bytecode/club/bootloader/InitialBootScreen.java
Normal file
|
@ -0,0 +1,85 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.Resources;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 04:12:21
|
||||
*/
|
||||
public class InitialBootScreen extends JFrame {
|
||||
private static final long serialVersionUID = -1098467609722393444L;
|
||||
|
||||
private JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
public InitialBootScreen() throws IOException {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setIconImages(Resources.iconList);
|
||||
|
||||
int i = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
|
||||
if(i >= 840)
|
||||
setSize(new Dimension(600, 800));
|
||||
else if(i >= 640)
|
||||
setSize(new Dimension(500, 600));
|
||||
else if(i >= 440)
|
||||
setSize(new Dimension(400, 400));
|
||||
else
|
||||
setSize(Toolkit.getDefaultToolkit().getScreenSize());
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Starting Up");
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
gridBagLayout.columnWidths = new int[]{0, 0};
|
||||
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
|
||||
gridBagLayout.rowWeights = new double[]{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
|
||||
getContentPane().setLayout(gridBagLayout);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
|
||||
gbc_scrollPane.gridheight = 24;
|
||||
gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
|
||||
gbc_scrollPane.fill = GridBagConstraints.BOTH;
|
||||
gbc_scrollPane.gridx = 0;
|
||||
gbc_scrollPane.gridy = 0;
|
||||
getContentPane().add(scrollPane, gbc_scrollPane);
|
||||
|
||||
JEditorPane editorPane = new JEditorPane();
|
||||
editorPane.setEditorKit(new HTMLEditorKit());
|
||||
|
||||
editorPane.setText(convertStreamToString(InitialBootScreen.class.getClassLoader().getResourceAsStream("resources/intro.html")));
|
||||
|
||||
scrollPane.setViewportView(editorPane);
|
||||
|
||||
GridBagConstraints gbc_progressBar = new GridBagConstraints();
|
||||
gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc_progressBar.gridx = 0;
|
||||
gbc_progressBar.gridy = 24;
|
||||
getContentPane().add(progressBar, gbc_progressBar);
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
static String convertStreamToString(java.io.InputStream is) throws IOException {
|
||||
@SuppressWarnings("resource")
|
||||
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
|
||||
String string = s.hasNext() ? s.next() : "";
|
||||
is.close();
|
||||
s.close();
|
||||
return string;
|
||||
}
|
||||
|
||||
public JProgressBar getProgressBar() {
|
||||
return progressBar;
|
||||
}
|
||||
}
|
142
src/the/bytecode/club/bootloader/JarContents.java
Normal file
142
src/the/bytecode/club/bootloader/JarContents.java
Normal file
|
@ -0,0 +1,142 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public class JarContents<C extends ClassNode> {
|
||||
|
||||
private final DataContainer<C> classContents;
|
||||
private final DataContainer<JarResource> resourceContents;
|
||||
|
||||
public JarContents() {
|
||||
classContents = new ClassNodeContainer<C>();
|
||||
resourceContents = new ResourceContainer();
|
||||
}
|
||||
|
||||
public JarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents) {
|
||||
this.classContents = classContents == null ? new ClassNodeContainer<C>() : classContents;
|
||||
this.resourceContents = resourceContents == null ? new ResourceContainer() : resourceContents;
|
||||
}
|
||||
|
||||
public final DataContainer<C> getClassContents() {
|
||||
return classContents;
|
||||
}
|
||||
|
||||
public final DataContainer<JarResource> getResourceContents() {
|
||||
return resourceContents;
|
||||
}
|
||||
|
||||
public void merge(JarContents<C> contents) {
|
||||
classContents.addAll(contents.classContents);
|
||||
resourceContents.addAll(contents.resourceContents);
|
||||
}
|
||||
|
||||
public JarContents<C> add(JarContents<C> contents) {
|
||||
List<C> c1 = classContents;
|
||||
List<C> c2 = contents.classContents;
|
||||
|
||||
List<JarResource> r1 = resourceContents;
|
||||
List<JarResource> r2 = contents.resourceContents;
|
||||
|
||||
List<C> c3 = new ArrayList<C>(c1.size() + c2.size());
|
||||
c3.addAll(c1);
|
||||
c3.addAll(c2);
|
||||
|
||||
List<JarResource> r3 = new ArrayList<JarResource>(r1.size() + r2.size());
|
||||
r3.addAll(r1);
|
||||
r3.addAll(r2);
|
||||
|
||||
return new JarContents<C>(new ClassNodeContainer<>(c3), new ResourceContainer(r3));
|
||||
}
|
||||
|
||||
public static class ClassNodeContainer<C extends ClassNode> extends DataContainer<C> {
|
||||
private static final long serialVersionUID = -6169578803641192235L;
|
||||
|
||||
private Map<String, C> lastMap = new HashMap<String, C>();
|
||||
private boolean invalidated;
|
||||
|
||||
public ClassNodeContainer() {
|
||||
this(16);
|
||||
}
|
||||
|
||||
public ClassNodeContainer(int cap) {
|
||||
super(cap);
|
||||
}
|
||||
|
||||
public ClassNodeContainer(Collection<C> data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(C c) {
|
||||
invalidated = true;
|
||||
return super.add(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends C> c) {
|
||||
invalidated = true;
|
||||
return super.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object c) {
|
||||
invalidated = true;
|
||||
return super.remove(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, C> namedMap() {
|
||||
if (invalidated) {
|
||||
invalidated = false;
|
||||
Map<String, C> nodeMap = new HashMap<String, C>();
|
||||
Iterator<C> it = iterator();
|
||||
while (it.hasNext()) {
|
||||
C cn = it.next();
|
||||
if (nodeMap.containsKey(cn.name)) {
|
||||
it.remove();
|
||||
} else {
|
||||
nodeMap.put(cn.name, cn);
|
||||
}
|
||||
}
|
||||
lastMap = nodeMap;
|
||||
}
|
||||
return lastMap;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ResourceContainer extends DataContainer<JarResource> {
|
||||
private static final long serialVersionUID = -6169578803641192235L;
|
||||
|
||||
public ResourceContainer() {
|
||||
this(16);
|
||||
}
|
||||
|
||||
public ResourceContainer(int cap) {
|
||||
super(cap);
|
||||
}
|
||||
|
||||
public ResourceContainer(List<JarResource> data) {
|
||||
addAll(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, JarResource> namedMap() {
|
||||
Map<String, JarResource> map = new HashMap<String, JarResource>();
|
||||
for (JarResource resource : this) {
|
||||
map.put(resource.getName(), resource);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
105
src/the/bytecode/club/bootloader/JarInfo.java
Normal file
105
src/the/bytecode/club/bootloader/JarInfo.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Holds information about a single local or external JarFile.
|
||||
*
|
||||
* @author Bibl
|
||||
* @created ages ago
|
||||
*/
|
||||
public class JarInfo {
|
||||
|
||||
private final String path;
|
||||
private final JarType type;
|
||||
|
||||
/**
|
||||
* Creates a new holder as the JarFile is on the local system.
|
||||
*
|
||||
* @param path Path to jar.
|
||||
*/
|
||||
public JarInfo(File path) {
|
||||
this(path.getAbsolutePath(), JarType.FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new holder.
|
||||
*
|
||||
* @param path Path to jar.
|
||||
* @param type Type of jar.
|
||||
*/
|
||||
public JarInfo(String path, JarType type) {
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new holder.
|
||||
*
|
||||
* @param url URL to jar.
|
||||
*/
|
||||
public JarInfo(URL url) {
|
||||
this(url.toExternalForm(), JarType.WEB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Real path to JarFile.
|
||||
*/
|
||||
public final String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public final JarType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string ready for a {@link JarURLConnection} to connect to.
|
||||
*
|
||||
* @param url Location of the JarFile.
|
||||
* @param type Type of JarFile.
|
||||
* @return The formatted url.
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public URL formattedURL() throws MalformedURLException {
|
||||
StringBuilder sb = new StringBuilder().append("jar:").append(type.prefix()).append(path);
|
||||
if (type.equals(JarType.FILE) && !path.endsWith(".jar")) {
|
||||
File file = new File(path);
|
||||
if (!file.exists())
|
||||
sb.append(".jar");
|
||||
}
|
||||
sb.append("!/");
|
||||
return new URL(sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = (prime * result) + ((path == null) ? 0 : path.hashCode());
|
||||
result = (prime * result) + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
JarInfo other = (JarInfo) obj;
|
||||
if (path == null) {
|
||||
if (other.path != null)
|
||||
return false;
|
||||
} else if (!path.equals(other.path))
|
||||
return false;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
54
src/the/bytecode/club/bootloader/JarResource.java
Normal file
54
src/the/bytecode/club/bootloader/JarResource.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public class JarResource {
|
||||
|
||||
private final String name;
|
||||
private final byte[] data;
|
||||
|
||||
public JarResource(String name, byte[] data) {
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = (prime * result) + Arrays.hashCode(data);
|
||||
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
JarResource other = (JarResource) obj;
|
||||
if (!Arrays.equals(data, other.data))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
25
src/the/bytecode/club/bootloader/JarType.java
Normal file
25
src/the/bytecode/club/bootloader/JarType.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
/**
|
||||
* Type of Jar Stored.
|
||||
* @author Bibl
|
||||
* @created ages ago
|
||||
*/
|
||||
public enum JarType {
|
||||
|
||||
/** Local file **/
|
||||
FILE("file:"),
|
||||
/** External URL **/
|
||||
WEB("");
|
||||
|
||||
private final String prefix;
|
||||
|
||||
private JarType(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
/** Gets the prefix for the JarURLConnection. **/
|
||||
public String prefix() {
|
||||
return prefix;
|
||||
}
|
||||
}
|
150
src/the/bytecode/club/bootloader/LibraryClassLoader.java
Normal file
150
src/the/bytecode/club/bootloader/LibraryClassLoader.java
Normal file
|
@ -0,0 +1,150 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 19 Jul 2015 02:48:41
|
||||
*
|
||||
* TODO: Resource loading
|
||||
*/
|
||||
public class LibraryClassLoader extends ClassLoader implements ILoader {
|
||||
|
||||
private final Set<JarContents<ClassNode>> binded;
|
||||
private final Map<String, Class<?>> classCache;
|
||||
private final ClassTree tree;
|
||||
|
||||
public LibraryClassLoader() {
|
||||
binded = new HashSet<JarContents<ClassNode>>();
|
||||
classCache = new HashMap<String, Class<?>>();
|
||||
tree = new ClassTree();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see the.bytecode.club.bytecodeviewer.loadermodel.ILoader#bind(the.bytecode.club.bytecodeviewer.loadermodel.ExternalResource)
|
||||
*/
|
||||
@Override
|
||||
public void bind(ExternalResource<JarContents<ClassNode>> resource) {
|
||||
try {
|
||||
JarContents<ClassNode> contents = resource.load();
|
||||
if(contents != null) {
|
||||
binded.add(contents);
|
||||
tree.build(contents.getClassContents().namedMap());
|
||||
} else {
|
||||
System.err.println("Null contents?");
|
||||
}
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see the.bytecode.club.bytecodeviewer.loadermodel.ILoader#loadClass(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError {
|
||||
String byte_name = name.replace(".", "/");
|
||||
if(classCache.containsKey(byte_name))
|
||||
return classCache.get(byte_name);
|
||||
|
||||
ClassNode cn = null;
|
||||
for(JarContents<ClassNode> contents : binded) {
|
||||
cn = contents.getClassContents().namedMap().get(byte_name);
|
||||
if(cn != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if(cn != null) {
|
||||
Class<?> klass = define(cn);
|
||||
if(klass != null) {
|
||||
classCache.put(byte_name, klass);
|
||||
return klass;
|
||||
}
|
||||
}
|
||||
|
||||
return super.loadClass(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected Class<?> define(ClassNode cn) {
|
||||
ClassWriter writer = new ResolvingClassWriter(tree);
|
||||
cn.accept(cn);
|
||||
byte[] bytes = writer.toByteArray();
|
||||
return defineClass(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
public class ResolvingClassWriter extends ClassWriter {
|
||||
|
||||
private final ClassTree classTree;
|
||||
|
||||
public ResolvingClassWriter(ClassTree classTree) {
|
||||
super(ClassWriter.COMPUTE_FRAMES);
|
||||
this.classTree = classTree;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
void update(Map<String, ClassNode> classes) {
|
||||
classTree.build(classes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommonSuperClass(final String type1, final String type2) {
|
||||
ClassNode ccn = classTree.getClass(type1);
|
||||
ClassNode dcn = classTree.getClass(type2);
|
||||
|
||||
//System.out.println(type1 + " " + type2);
|
||||
if(ccn == null) {
|
||||
classTree.build(create_quick(type1));
|
||||
return getCommonSuperClass(type1, type2);
|
||||
}
|
||||
|
||||
if(dcn == null) {
|
||||
classTree.build(create_quick(type2));
|
||||
return getCommonSuperClass(type1, type2);
|
||||
}
|
||||
|
||||
Set<ClassNode> c = classTree.getSupers(ccn);
|
||||
Set<ClassNode> d = classTree.getSupers(dcn);
|
||||
|
||||
if(c.contains(dcn))
|
||||
return type1;
|
||||
|
||||
if(d.contains(ccn))
|
||||
return type2;
|
||||
|
||||
if(Modifier.isInterface(ccn.access) || Modifier.isInterface(dcn.access)) {
|
||||
return "java/lang/Object";
|
||||
} else {
|
||||
do {
|
||||
ClassNode nccn = classTree.getClass(ccn.superName);
|
||||
if(nccn == null)
|
||||
break;
|
||||
ccn = nccn;
|
||||
c = classTree.getSupers(ccn);
|
||||
} while(!c.contains(dcn));
|
||||
return ccn.name;
|
||||
}
|
||||
}
|
||||
|
||||
public ClassNode create_quick(String name) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(name);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
|
||||
return cn;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
src/the/bytecode/club/bootloader/LocateableJarContents.java
Normal file
28
src/the/bytecode/club/bootloader/LocateableJarContents.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public class LocateableJarContents<C extends ClassNode> extends JarContents<C> {
|
||||
|
||||
private final URL[] jarUrls;
|
||||
|
||||
public LocateableJarContents(URL... jarUrls) {
|
||||
super();
|
||||
this.jarUrls = jarUrls;
|
||||
}
|
||||
|
||||
public LocateableJarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents, URL... jarUrls) {
|
||||
super(classContents, resourceContents);
|
||||
this.jarUrls = jarUrls;
|
||||
}
|
||||
|
||||
public URL[] getJarUrls() {
|
||||
return jarUrls;
|
||||
}
|
||||
}
|
13
src/the/bytecode/club/bootloader/NullCreator.java
Normal file
13
src/the/bytecode/club/bootloader/NullCreator.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public class NullCreator<V> implements ValueCreator<V> {
|
||||
|
||||
@Override
|
||||
public V create() {
|
||||
return null;
|
||||
}
|
||||
}
|
31
src/the/bytecode/club/bootloader/NullPermeableHashMap.java
Normal file
31
src/the/bytecode/club/bootloader/NullPermeableHashMap.java
Normal file
|
@ -0,0 +1,31 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public class NullPermeableHashMap<K, V> extends HashMap<K, V> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final ValueCreator<V> creator;
|
||||
|
||||
public NullPermeableHashMap(ValueCreator<V> creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public NullPermeableHashMap() {
|
||||
this(new NullCreator<V>());
|
||||
}
|
||||
|
||||
public V getNonNull(K k) {
|
||||
V val = get(k);
|
||||
if (val == null) {
|
||||
val = creator.create();
|
||||
put(k, val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
16
src/the/bytecode/club/bootloader/SetCreator.java
Normal file
16
src/the/bytecode/club/bootloader/SetCreator.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created 25 May 2015 (actually before this)
|
||||
*/
|
||||
public class SetCreator<T> implements ValueCreator<Set<T>> {
|
||||
|
||||
@Override
|
||||
public Set<T> create() {
|
||||
return new HashSet<T>();
|
||||
}
|
||||
}
|
10
src/the/bytecode/club/bootloader/ValueCreator.java
Normal file
10
src/the/bytecode/club/bootloader/ValueCreator.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package the.bytecode.club.bootloader;
|
||||
|
||||
/**
|
||||
* @author Bibl (don't ban me pls)
|
||||
* @created ages ago
|
||||
*/
|
||||
public abstract interface ValueCreator<V> {
|
||||
|
||||
public abstract V create();
|
||||
}
|
212
src/the/bytecode/club/bytecodeviewer/BootScreen.java
Normal file
212
src/the/bytecode/club/bytecodeviewer/BootScreen.java
Normal file
|
@ -0,0 +1,212 @@
|
|||
package the.bytecode.club.bytecodeviewer;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
/**
|
||||
* Automatic updater for BCV libraries
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*/
|
||||
|
||||
public class BootScreen extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = -1098467609722393444L;
|
||||
|
||||
private static boolean FIRST_BOOT = false;
|
||||
|
||||
private JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
public BootScreen() throws IOException {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setIconImages(Resources.iconList);
|
||||
|
||||
int i = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
|
||||
if(i >= 840)
|
||||
setSize(new Dimension(600, 800));
|
||||
else if(i >= 640)
|
||||
setSize(new Dimension(500, 600));
|
||||
else if(i >= 440)
|
||||
setSize(new Dimension(400, 400));
|
||||
else
|
||||
setSize(Toolkit.getDefaultToolkit().getScreenSize());
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Starting Up");
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
gridBagLayout.columnWidths = new int[]{0, 0};
|
||||
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
|
||||
gridBagLayout.rowWeights = new double[]{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
|
||||
getContentPane().setLayout(gridBagLayout);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
|
||||
gbc_scrollPane.gridheight = 24;
|
||||
gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
|
||||
gbc_scrollPane.fill = GridBagConstraints.BOTH;
|
||||
gbc_scrollPane.gridx = 0;
|
||||
gbc_scrollPane.gridy = 0;
|
||||
getContentPane().add(scrollPane, gbc_scrollPane);
|
||||
|
||||
JEditorPane editorPane = new JEditorPane();
|
||||
editorPane.setEditorKit(new HTMLEditorKit());
|
||||
|
||||
editorPane.setText(convertStreamToString(BytecodeViewer.class.getClassLoader().getResourceAsStream("resources/intro.html")));
|
||||
|
||||
scrollPane.setViewportView(editorPane);
|
||||
|
||||
GridBagConstraints gbc_progressBar = new GridBagConstraints();
|
||||
gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc_progressBar.gridx = 0;
|
||||
gbc_progressBar.gridy = 24;
|
||||
getContentPane().add(progressBar, gbc_progressBar);
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
static String convertStreamToString(java.io.InputStream is) throws IOException {
|
||||
@SuppressWarnings("resource")
|
||||
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
|
||||
String string = s.hasNext() ? s.next() : "";
|
||||
is.close();
|
||||
s.close();
|
||||
return string;
|
||||
}
|
||||
|
||||
public void DO_FIRST_BOOT(String args[], int CLI) {
|
||||
if(CLI == -1)
|
||||
return;
|
||||
|
||||
if(CLI == 1)
|
||||
this.setVisible(true);
|
||||
|
||||
if(FIRST_BOOT)
|
||||
return;
|
||||
|
||||
FIRST_BOOT = true;
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Libraries...");
|
||||
System.out.println("Checking Libraries...");
|
||||
|
||||
try {
|
||||
int completedCheck = 0;
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Krakatau...");
|
||||
System.out.println("Checking krakatau");
|
||||
|
||||
File krakatauZip = null;
|
||||
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("krakatau-")) {
|
||||
BytecodeViewer.krakatauVersion = f.getName().split("-")[1].split("\\.")[0];
|
||||
krakatauZip = f;
|
||||
}
|
||||
}
|
||||
|
||||
for(File f : new File(BytecodeViewer.getBCVDirectory()).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("krakatau_") && !f.getName().split("_")[1].split("\\.")[0].equals(BytecodeViewer.krakatauVersion)) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
|
||||
System.out.println("Removing oudated " + f.getName());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.krakatauWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion + BytecodeViewer.fs + "Krakatau-master";
|
||||
File krakatauDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion);
|
||||
if(!krakatauDirectory.exists()) {
|
||||
try {
|
||||
setTitle("Bytecode Viewer Boot Screen - Updating to "+krakatauDirectory.getName()+"...");
|
||||
ZipUtils.unzipFilesToPath(krakatauZip.getAbsolutePath(), krakatauDirectory.getAbsolutePath());
|
||||
System.out.println("Updated to krakatau v" + BytecodeViewer.krakatauVersion);
|
||||
} catch(Exception e) {
|
||||
BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly corrupt). Restart BCV."+BytecodeViewer.nl+
|
||||
"If the error persists contact @Konloch.");
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
krakatauZip.delete();
|
||||
}
|
||||
}
|
||||
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Enjarify...");
|
||||
System.out.println("Checking enjarify");
|
||||
|
||||
File enjarifyZip = null;
|
||||
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("enjarify-")) {
|
||||
BytecodeViewer.enjarifyVersion = f.getName().split("-")[1].split("\\.")[0];
|
||||
enjarifyZip = f;
|
||||
}
|
||||
}
|
||||
|
||||
for(File f : new File(BytecodeViewer.getBCVDirectory()).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("enjarify_") && !f.getName().split("_")[1].split("\\.")[0].equals(BytecodeViewer.enjarifyVersion)) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
|
||||
System.out.println("Removing oudated " + f.getName());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.enjarifyWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion + BytecodeViewer.fs + "enjarify-master";
|
||||
File enjarifyDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion);
|
||||
if(!enjarifyDirectory.exists()) {
|
||||
try {
|
||||
setTitle("Bytecode Viewer Boot Screen - Updating to "+enjarifyDirectory.getName()+"...");
|
||||
ZipUtils.unzipFilesToPath(enjarifyZip.getAbsolutePath(), enjarifyDirectory.getAbsolutePath());
|
||||
System.out.println("Updated to enjarify v" + BytecodeViewer.enjarifyVersion);
|
||||
} catch(Exception e) {
|
||||
BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart BCV."+BytecodeViewer.nl+
|
||||
"If the error persists contact @Konloch.");
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
enjarifyZip.delete();
|
||||
}
|
||||
}
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Booting!");
|
||||
|
||||
} catch(Exception e) {
|
||||
Settings.saveGUI();
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
e.printStackTrace();
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI("Bytecode Viewer ran into an error while booting, trying to force it anyways."+ BytecodeViewer.nl+ BytecodeViewer.nl+
|
||||
"Please ensure you have an active internet connection and restart BCV. If this presists please visit http://github.com/Konloch/Bytecode-Viewer or http://bytecodeviewer.com"+ BytecodeViewer.nl + BytecodeViewer.nl + sw.toString());
|
||||
}
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Finished");
|
||||
|
||||
if(CLI == 1)
|
||||
BytecodeViewer.BOOT(args, false);
|
||||
else {
|
||||
BytecodeViewer.BOOT(args, true);
|
||||
CommandLineInput.executeCommandLine(args);
|
||||
}
|
||||
|
||||
this.setVisible(false);
|
||||
}
|
||||
}
|
|
@ -34,7 +34,6 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
|
||||
import the.bytecode.club.bytecodeviewer.gui.ClassViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane;
|
||||
import the.bytecode.club.bytecodeviewer.gui.BootScreen;
|
||||
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
|
||||
import the.bytecode.club.bytecodeviewer.gui.RunOptions;
|
||||
import the.bytecode.club.bytecodeviewer.gui.SearchingPane;
|
||||
|
@ -323,6 +322,7 @@ public class BytecodeViewer {
|
|||
};
|
||||
|
||||
public static Thread PingBack = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
new HTTPRequest(new URL("https://bytecodeviewer.com/add.php")).read();
|
||||
|
|
|
@ -1,403 +0,0 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui;
|
||||
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JProgressBar;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import java.awt.Insets;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.CommandLineInput;
|
||||
import the.bytecode.club.bytecodeviewer.Resources;
|
||||
import the.bytecode.club.bytecodeviewer.Settings;
|
||||
import the.bytecode.club.bytecodeviewer.ZipUtils;
|
||||
import me.konloch.kontainer.io.HTTPRequest;
|
||||
|
||||
/**
|
||||
* Automatic updater for BCV libraries
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*/
|
||||
|
||||
public class BootScreen extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = -1098467609722393444L;
|
||||
|
||||
private static boolean FIRST_BOOT = false;
|
||||
|
||||
private JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
public BootScreen() throws IOException {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setIconImages(Resources.iconList);
|
||||
|
||||
int i = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
|
||||
if(i >= 840)
|
||||
setSize(new Dimension(600, 800));
|
||||
else if(i >= 640)
|
||||
setSize(new Dimension(500, 600));
|
||||
else if(i >= 440)
|
||||
setSize(new Dimension(400, 400));
|
||||
else
|
||||
setSize(Toolkit.getDefaultToolkit().getScreenSize());
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Starting Up");
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
gridBagLayout.columnWidths = new int[]{0, 0};
|
||||
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
|
||||
gridBagLayout.rowWeights = new double[]{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
|
||||
getContentPane().setLayout(gridBagLayout);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
|
||||
gbc_scrollPane.gridheight = 24;
|
||||
gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
|
||||
gbc_scrollPane.fill = GridBagConstraints.BOTH;
|
||||
gbc_scrollPane.gridx = 0;
|
||||
gbc_scrollPane.gridy = 0;
|
||||
getContentPane().add(scrollPane, gbc_scrollPane);
|
||||
|
||||
JEditorPane editorPane = new JEditorPane();
|
||||
editorPane.setEditorKit(new HTMLEditorKit());
|
||||
|
||||
editorPane.setText(convertStreamToString(BytecodeViewer.class.getClassLoader().getResourceAsStream("resources/intro.html")));
|
||||
|
||||
scrollPane.setViewportView(editorPane);
|
||||
|
||||
GridBagConstraints gbc_progressBar = new GridBagConstraints();
|
||||
gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc_progressBar.gridx = 0;
|
||||
gbc_progressBar.gridy = 24;
|
||||
getContentPane().add(progressBar, gbc_progressBar);
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
static String convertStreamToString(java.io.InputStream is) throws IOException {
|
||||
@SuppressWarnings("resource")
|
||||
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
|
||||
String string = s.hasNext() ? s.next() : "";
|
||||
is.close();
|
||||
s.close();
|
||||
return string;
|
||||
}
|
||||
|
||||
public void DO_FIRST_BOOT(String args[], int CLI) {
|
||||
if(CLI == -1)
|
||||
return;
|
||||
|
||||
if(CLI == 1)
|
||||
this.setVisible(true);
|
||||
|
||||
if(FIRST_BOOT)
|
||||
return;
|
||||
|
||||
FIRST_BOOT = true;
|
||||
boolean foundAtleastOne = false;
|
||||
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Libraries...");
|
||||
System.out.println("Checking Libraries...");
|
||||
|
||||
File libsDirectory = new File(BytecodeViewer.libsDirectory);
|
||||
|
||||
try {
|
||||
int completedCheck = 0;
|
||||
List<String> urlList = new ArrayList<String>();
|
||||
HTTPRequest req = new HTTPRequest(new URL("https://github.com/Konloch/bytecode-viewer/tree/master/libs"));
|
||||
for(String s : req.read())
|
||||
if(s.contains("href=\"/Konloch/bytecode-viewer/blob/master/libs/")) {
|
||||
urlList.add("https://github.com"+s.split("<a href=")[1].split("\"")[1]);
|
||||
foundAtleastOne = true;
|
||||
}
|
||||
|
||||
if(!foundAtleastOne) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI("Bytecode Viewer ran into an issue, for some reason github is not returning what we're expecting. Please try rebooting, if this issue persists please contact @Konloch.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length >= 1)
|
||||
if(args[0].equalsIgnoreCase("-clean"))
|
||||
libsDirectory.delete();
|
||||
|
||||
if(!libsDirectory.exists())
|
||||
libsDirectory.mkdir();
|
||||
|
||||
List<String> libsList = new ArrayList<String>();
|
||||
List<String> libsFileList = new ArrayList<String>();
|
||||
for(File f : libsDirectory.listFiles()) {
|
||||
libsList.add(f.getName());
|
||||
libsFileList.add(f.getAbsolutePath());
|
||||
}
|
||||
|
||||
progressBar.setMaximum(urlList.size()*2);
|
||||
|
||||
for(String s : urlList) {
|
||||
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length(), s.length());
|
||||
if(!libsList.contains(fileName)) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Downloading " + fileName);
|
||||
System.out.println("Downloading " + fileName);
|
||||
boolean passed = false;
|
||||
while(!passed) {
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName).openConnection().getInputStream();
|
||||
fos = new FileOutputStream(BytecodeViewer.libsDirectory + BytecodeViewer.fs + fileName);
|
||||
System.out.println("Downloading from "+s);
|
||||
byte[] buffer = new byte[8192];
|
||||
int len;
|
||||
int downloaded = 0;
|
||||
boolean flag = false;
|
||||
while ((len = is.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
fos.flush();
|
||||
downloaded += 8192;
|
||||
int mbs = downloaded / 1048576;
|
||||
if(mbs % 5 == 0 && mbs != 0) {
|
||||
if(!flag)
|
||||
System.out.println("Downloaded " + mbs + "MBs so far");
|
||||
flag = true;
|
||||
} else
|
||||
flag = false;
|
||||
}
|
||||
libsFileList.add(BytecodeViewer.libsDirectory + BytecodeViewer.fs + fileName);
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
fos.flush();
|
||||
}
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Download finished!");
|
||||
passed = true;
|
||||
}
|
||||
}
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
}
|
||||
|
||||
if(BytecodeViewer.deleteForiegnLibraries) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking & Deleting Foreign/Outdated Libraries...");
|
||||
System.out.println("Checking & Deleting foreign/outdated libraries");
|
||||
for(String s : libsFileList) {
|
||||
File f = new File(s);
|
||||
boolean delete = true;
|
||||
for(String urlS : urlList) {
|
||||
String fileName = urlS.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length(), urlS.length());
|
||||
if(fileName.equals(f.getName()))
|
||||
delete = false;
|
||||
}
|
||||
if(delete) {
|
||||
f.delete();
|
||||
System.out.println("Detected & Deleted Foriegn/Outdated Jar/File: " + f.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Loading Libraries...");
|
||||
System.out.println("Loading libraries...");
|
||||
|
||||
for(String s : libsFileList ) {
|
||||
if(s.endsWith(".jar")) {
|
||||
File f = new File(s);
|
||||
if(f.exists()) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Loading Library " + f.getName());
|
||||
System.out.println("Loading library " + f.getName());
|
||||
|
||||
try {
|
||||
JarFile jarFile = new JarFile(s);
|
||||
Enumeration<JarEntry> e = jarFile.entries();
|
||||
ClassPathHack.addFile(f);
|
||||
while (e.hasMoreElements()) {
|
||||
JarEntry je = (JarEntry) e.nextElement();
|
||||
if(je.isDirectory() || !je.getName().endsWith(".class")){
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String className = je.getName().substring(0,je.getName().length()-6);
|
||||
className = className.replace('/', '.');
|
||||
ClassLoader.getSystemClassLoader().loadClass(className);
|
||||
} catch(java.lang.VerifyError | java.lang.ExceptionInInitializerError | java.lang.IncompatibleClassChangeError | java.lang.NoClassDefFoundError | Exception e2) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
System.out.println("Succesfully loaded " + f.getName());
|
||||
jarFile.close();
|
||||
} catch(java.util.zip.ZipException e) {
|
||||
e.printStackTrace();
|
||||
f.delete();
|
||||
BytecodeViewer.showMessage("Error, Library " + f.getName() + " is corrupt, please restart to redownload it.");
|
||||
}
|
||||
}
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Krakatau...");
|
||||
System.out.println("Checking krakatau");
|
||||
|
||||
File krakatauZip = null;
|
||||
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("krakatau-")) {
|
||||
BytecodeViewer.krakatauVersion = f.getName().split("-")[1].split("\\.")[0];
|
||||
krakatauZip = f;
|
||||
}
|
||||
}
|
||||
|
||||
for(File f : new File(BytecodeViewer.getBCVDirectory()).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("krakatau_") && !f.getName().split("_")[1].split("\\.")[0].equals(BytecodeViewer.krakatauVersion)) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
|
||||
System.out.println("Removing oudated " + f.getName());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.krakatauWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion + BytecodeViewer.fs + "Krakatau-master";
|
||||
File krakatauDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion);
|
||||
if(!krakatauDirectory.exists()) {
|
||||
try {
|
||||
setTitle("Bytecode Viewer Boot Screen - Updating to "+krakatauDirectory.getName()+"...");
|
||||
ZipUtils.unzipFilesToPath(krakatauZip.getAbsolutePath(), krakatauDirectory.getAbsolutePath());
|
||||
System.out.println("Updated to krakatau v" + BytecodeViewer.krakatauVersion);
|
||||
} catch(Exception e) {
|
||||
BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly corrupt). Restart BCV."+BytecodeViewer.nl+
|
||||
"If the error persists contact @Konloch.");
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
krakatauZip.delete();
|
||||
}
|
||||
}
|
||||
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Checking Enjarify...");
|
||||
System.out.println("Checking enjarify");
|
||||
|
||||
File enjarifyZip = null;
|
||||
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("enjarify-")) {
|
||||
BytecodeViewer.enjarifyVersion = f.getName().split("-")[1].split("\\.")[0];
|
||||
enjarifyZip = f;
|
||||
}
|
||||
}
|
||||
|
||||
for(File f : new File(BytecodeViewer.getBCVDirectory()).listFiles()) {
|
||||
if(f.getName().toLowerCase().startsWith("enjarify_") && !f.getName().split("_")[1].split("\\.")[0].equals(BytecodeViewer.enjarifyVersion)) {
|
||||
setTitle("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
|
||||
System.out.println("Removing oudated " + f.getName());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.enjarifyWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion + BytecodeViewer.fs + "enjarify-master";
|
||||
File enjarifyDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion);
|
||||
if(!enjarifyDirectory.exists()) {
|
||||
try {
|
||||
setTitle("Bytecode Viewer Boot Screen - Updating to "+enjarifyDirectory.getName()+"...");
|
||||
ZipUtils.unzipFilesToPath(enjarifyZip.getAbsolutePath(), enjarifyDirectory.getAbsolutePath());
|
||||
System.out.println("Updated to enjarify v" + BytecodeViewer.enjarifyVersion);
|
||||
} catch(Exception e) {
|
||||
BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart BCV."+BytecodeViewer.nl+
|
||||
"If the error persists contact @Konloch.");
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
enjarifyZip.delete();
|
||||
}
|
||||
}
|
||||
completedCheck++;
|
||||
progressBar.setValue(completedCheck);
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Booting!");
|
||||
|
||||
} catch(Exception e) {
|
||||
Settings.saveGUI();
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
e.printStackTrace();
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI("Bytecode Viewer ran into an error while booting, trying to force it anyways."+ BytecodeViewer.nl+ BytecodeViewer.nl+
|
||||
"Please ensure you have an active internet connection and restart BCV. If this presists please visit http://github.com/Konloch/Bytecode-Viewer or http://bytecodeviewer.com"+ BytecodeViewer.nl + BytecodeViewer.nl + sw.toString());
|
||||
}
|
||||
|
||||
setTitle("Bytecode Viewer Boot Screen - Finished");
|
||||
|
||||
if(CLI == 1)
|
||||
BytecodeViewer.BOOT(args, false);
|
||||
else {
|
||||
BytecodeViewer.BOOT(args, true);
|
||||
CommandLineInput.executeCommandLine(args);
|
||||
}
|
||||
|
||||
this.setVisible(false);
|
||||
}
|
||||
|
||||
public static class ClassPathHack {
|
||||
private static final Class<?>[] parameters = new Class[] {URL.class};
|
||||
|
||||
public static void addFile(File f) throws IOException {
|
||||
// f.toURL is deprecated
|
||||
addURL(f.toURI().toURL());
|
||||
}
|
||||
|
||||
protected static void addURL(URL u) throws IOException {
|
||||
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
Class<?> sysclass = URLClassLoader.class;
|
||||
|
||||
try {
|
||||
Method method = sysclass.getDeclaredMethod("addURL", parameters);
|
||||
method.setAccessible(true);
|
||||
method.invoke(sysloader, u);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue