Merge pull request #60 from TheBiblMan/master

faster loading. (please fix this fucking code, it's too bad) -Bibl
This commit is contained in:
Kalen (Konloch) Kinloch 2015-07-18 22:35:54 -06:00
commit fbd4d341aa
21 changed files with 1498 additions and 404 deletions

View 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();
}
}

View 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());
}
}
}

View 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);
}
}

View 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();
}

View 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;
}
}

View 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();
}
}

View 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;
}

View 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;
}
}

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>();
}
}

View 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();
}

View 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);
}
}

View file

@ -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();

View file

@ -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();
}
}
}
}