2021-07-21 19:55:03 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.bootloader;
|
|
|
|
|
|
|
|
import de.skuzzle.semantic.Version;
|
|
|
|
import me.konloch.kontainer.io.HTTPRequest;
|
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|
|
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
|
|
|
import the.bytecode.club.bytecodeviewer.api.BCV;
|
|
|
|
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
|
|
|
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
|
|
|
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
import java.awt.*;
|
|
|
|
import java.io.*;
|
|
|
|
import java.net.URI;
|
|
|
|
import java.net.URL;
|
|
|
|
|
|
|
|
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Konloch
|
|
|
|
*/
|
|
|
|
public class UpdateCheck implements Runnable
|
|
|
|
{
|
|
|
|
//just brute force download the url path
|
|
|
|
//one of these works for every single version of BCV
|
|
|
|
public static final String[] remoteGithubReleases = new String[]
|
|
|
|
{
|
|
|
|
//current url scheme since v2.9.12
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.jar",
|
|
|
|
//for v2.9.10 and v2.9.11
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/{VERSION}/Bytecode-Viewer-{VERSION}.jar",
|
|
|
|
//for v2.7.0 to v2.9.8
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.zip",
|
|
|
|
//for v2.0 to v2.6.0
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.jar",
|
|
|
|
//for v1.1 to v1.5.3
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/b{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
|
|
|
|
//for v1.4
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/b.{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
|
|
|
|
//for v1.0
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/B{VERSION}/BytecodeViewer.jar",
|
2021-07-21 23:19:27 +00:00
|
|
|
//zip variant of current url scheme since v2.9.12 (not currently used but incase it ever does)
|
|
|
|
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.zip",
|
2021-07-21 19:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//a list of all of the released versions of BCV
|
|
|
|
public static final String[] versions = new String[]
|
|
|
|
{
|
2021-07-23 16:47:45 +00:00
|
|
|
//"2.11.0",
|
|
|
|
//"2.10.15",
|
2021-07-21 19:55:03 +00:00
|
|
|
"2.10.14",
|
|
|
|
"2.10.13",
|
|
|
|
"2.10.12",
|
|
|
|
"2.10.11",
|
|
|
|
"2.9.22",
|
|
|
|
"2.9.21",
|
|
|
|
"2.9.20",
|
|
|
|
"2.9.19",
|
|
|
|
"2.9.18",
|
|
|
|
"2.9.17",
|
|
|
|
"2.9.16",
|
|
|
|
"2.9.15",
|
|
|
|
"2.9.14",
|
|
|
|
"2.9.13",
|
|
|
|
"2.9.12",
|
|
|
|
"2.9.11",
|
|
|
|
"2.9.10", //broken due to repo change
|
|
|
|
"2.9.8", //broken due to repo change & zip
|
|
|
|
"2.9.7", //broken due to repo change & zip
|
|
|
|
"2.9.6", //zip
|
|
|
|
"2.9.5", //zip
|
|
|
|
"2.9.4", //zip
|
|
|
|
"2.9.3", //zip
|
|
|
|
"2.9.2", //zip
|
|
|
|
"2.9.1", //zip
|
|
|
|
"2.9.0", //zip
|
|
|
|
"2.8.1", //zip
|
|
|
|
"2.8.0", //zip
|
|
|
|
"2.7.1", //zip
|
|
|
|
"2.7.0", //zip
|
|
|
|
"2.6.0",
|
|
|
|
"2.5.2",
|
|
|
|
"2.5.1",
|
|
|
|
"2.5.0",
|
|
|
|
"2.4.0",
|
|
|
|
"2.3.0",
|
|
|
|
"2.2.1",
|
|
|
|
"2.2.0",
|
|
|
|
"2.1.1",
|
|
|
|
"2.1.0",
|
|
|
|
"2.0.1",
|
|
|
|
"2.0",
|
|
|
|
"1.5.3",
|
|
|
|
"1.5.2",
|
|
|
|
"1.5.1",
|
|
|
|
"1.5",
|
|
|
|
"1.4",
|
|
|
|
"1.3.1",
|
|
|
|
"1.3",
|
|
|
|
"1.2",
|
|
|
|
"1.1",
|
|
|
|
"1.0",
|
|
|
|
};
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
HTTPRequest r = new HTTPRequest(new URL("https://raw.githubusercontent.com/Konloch/bytecode-viewer/master/VERSION"));
|
|
|
|
final Version version = Version.parseVersion(r.readSingle());
|
|
|
|
final Version localVersion = Version.parseVersion(VERSION);
|
|
|
|
|
|
|
|
try {
|
|
|
|
//developer version
|
2021-07-21 22:54:17 +00:00
|
|
|
if (Version.compare(localVersion, version) > 0)
|
2021-07-21 19:55:03 +00:00
|
|
|
return;
|
|
|
|
} catch (Exception ignored) { }
|
|
|
|
|
|
|
|
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version",
|
|
|
|
"Your version: " + localVersion + ", latest version: " + version + nl +
|
|
|
|
"What would you like to do?",
|
|
|
|
new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing (And Don't Ask Again)"});
|
|
|
|
|
|
|
|
int result = outdatedDialog.promptChoice();
|
|
|
|
|
|
|
|
if (result == 0)
|
|
|
|
{
|
|
|
|
if (Desktop.isDesktopSupported())
|
|
|
|
Desktop.getDesktop().browse(new URI("https://github.com/Konloch/bytecode-viewer/releases"));
|
|
|
|
else
|
|
|
|
BytecodeViewer.showMessage("Cannot open the page, please manually type it."
|
|
|
|
+ nl + "https://github.com/Konloch/bytecode-viewer/releases");
|
|
|
|
}
|
|
|
|
else if (result == 1)
|
|
|
|
{
|
|
|
|
//TODO move this to after the file extension has been found
|
|
|
|
final File file = promptFileSave("Jar Archives", "jar");
|
|
|
|
|
|
|
|
if(file != null)
|
|
|
|
{
|
|
|
|
Thread downloadThread = new Thread(() ->
|
|
|
|
downloadBCV(version.toString(), file, ()->{}, ()->{}), "Downloader");
|
|
|
|
downloadThread.start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(result == 2)
|
|
|
|
{
|
|
|
|
//TODO save version into a hashset called doNotPrompt
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static File promptFileSave(String description, String extension) throws IOException
|
|
|
|
{
|
|
|
|
JFileChooser fc = new FileChooser(new File("./").getCanonicalFile(),
|
|
|
|
"Select Save File", description, extension);
|
|
|
|
|
|
|
|
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
|
|
|
|
File file = null;
|
|
|
|
if (returnVal == JFileChooser.APPROVE_OPTION)
|
|
|
|
{
|
|
|
|
Configuration.setLastOpenDirectory(fc.getSelectedFile());
|
|
|
|
|
|
|
|
file = fc.getSelectedFile();
|
|
|
|
String nameLowercase = file.getAbsolutePath().toLowerCase();
|
|
|
|
if (!nameLowercase.endsWith(".jar"))
|
|
|
|
file = new File(file.getAbsolutePath() + ".jar");
|
|
|
|
|
|
|
|
if (file.exists())
|
|
|
|
{
|
|
|
|
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File",
|
|
|
|
"The file " + file + " exists, would you like to overwrite it?",
|
|
|
|
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
|
|
|
|
|
|
|
|
if (overwriteDialog.promptChoice() != 0)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
file.delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
//used to download all released versions of BCV
|
|
|
|
/*public static void main(String[] args)
|
|
|
|
{
|
|
|
|
BytecodeViewer.viewer = new MainViewerGUI();
|
|
|
|
for(String version : versions)
|
|
|
|
{
|
|
|
|
//TODO most are jars, check which are zip and append zip as needed
|
|
|
|
File file = new File("./" + version + ".zip");
|
|
|
|
if(!file.exists())
|
|
|
|
downloadBCV(version, file, () -> {}, () -> {});
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
private static void downloadBCV(String version, File saveTo, Runnable onFinish, Runnable onFail)
|
|
|
|
{
|
|
|
|
boolean found = false;
|
|
|
|
for(String urlAttempt : remoteGithubReleases)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
String url = urlAttempt.replace("{VERSION}", version);
|
|
|
|
|
|
|
|
if(validURl(url))
|
|
|
|
{
|
|
|
|
download(url, saveTo, onFinish);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (FileNotFoundException ex) {
|
|
|
|
//ignore 404s
|
|
|
|
} catch (Exception e) {
|
|
|
|
//print network errors but don't alert user
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!found)
|
|
|
|
{
|
|
|
|
BCV.logE("Failed to download BCV v" + version);
|
|
|
|
BytecodeViewer.showMessage("Unable to download BCV v" + version + ", please let Konloch know.");
|
|
|
|
onFail.run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean validURl(String url) throws Exception
|
|
|
|
{
|
|
|
|
HTTPRequest request = new HTTPRequest(new URL(url));
|
|
|
|
request.readSingle();
|
|
|
|
return request.getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void download(String url, File saveTo, Runnable onFinish) throws Exception
|
|
|
|
{
|
|
|
|
BCV.log("Downloading from: " + url);
|
|
|
|
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box."
|
|
|
|
+ nl + nl + "Expect this to take several minutes.");
|
|
|
|
|
|
|
|
InputStream is = new URL(url).openConnection().getInputStream();
|
|
|
|
FileOutputStream fos = new FileOutputStream(saveTo);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
try {
|
|
|
|
if (is != null)
|
|
|
|
is.close();
|
|
|
|
} finally {
|
|
|
|
fos.flush();
|
|
|
|
fos.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BCV.log("Download finished!");
|
|
|
|
BytecodeViewer.showMessage("Download successful! You can find the updated program at " + saveTo.getAbsolutePath());
|
|
|
|
|
|
|
|
onFinish.run();
|
|
|
|
}
|
|
|
|
}
|