32 Commits

Author SHA1 Message Date
marc barbier 379cfed69a bandwidth precision improvement 2021-07-10 17:49:12 +02:00
marc barbier f100e2d41b add version option 2021-07-10 17:11:33 +02:00
marc barbier a2a136a9fc refacto main 2021-07-10 16:59:44 +02:00
marc barbier 416f0b892e thread warning + better logging 2021-07-10 16:57:53 +02:00
marc barbier f726458f29 removed check 2021-07-10 16:53:47 +02:00
marc barbier 6799681c6b refactoring ModUpdater 2021-07-10 16:52:06 +02:00
marc barbier 155f7ada2e exception non blockante dans les threads 2021-07-09 23:28:33 +02:00
marc barbier c8c23cbe42 safer parse - direct download 2021-07-09 23:27:23 +02:00
marc barbier a93e180c60 safer parse 2021-07-09 23:26:09 +02:00
marc barbier b0c1519063 nb thread fix + corruption check 2021-07-09 19:26:04 +02:00
Marc BARBIER 47d9e8e392 bandwith wip 2021-07-09 17:36:08 +02:00
Marc BARBIER c64ddd90c5 reindent + add error 2021-07-09 15:09:12 +02:00
Marc barbier 2f1ecef3d6 Merge pull request #1 from Marc-Pierre-Barbier/add-license-1
Create LICENSE
2021-07-09 10:03:41 +02:00
Marc barbier 0cfe34d152 Create LICENSE 2021-07-09 10:03:26 +02:00
marc barbier d9d868050f fix bad fetch 2021-07-08 23:02:20 +02:00
marc barbier 1a52c650c5 debug 2021-07-08 22:42:14 +02:00
marc barbier 098f6876ed fix all copetition error 2021-07-08 22:13:16 +02:00
marc barbier 22727988fb fix remove 2021-07-08 18:19:58 +02:00
marc barbier b8a3a5aea9 add release to git ignore 2021-07-08 17:38:08 +02:00
marc barbier f27a4136f4 remove test release 2021-07-08 17:37:18 +02:00
marc barbier 330eeecd32 release script 2021-07-08 17:36:48 +02:00
marc barbier 024a401b42 verbose 2021-07-08 17:16:14 +02:00
marc barbier 3d9a44c99a threads ! :D 2021-07-08 17:10:29 +02:00
marc barbier 2a3c112b67 debug 2021-07-08 15:07:11 +02:00
marc barbier 77a3cdec7e check message 2021-07-08 14:24:24 +02:00
marc barbier 5c808de32c thisfix 2021-07-08 14:23:32 +02:00
marc barbier 9da3e668a8 refactor global fin a tester 2021-07-08 14:23:07 +02:00
marc barbier f83140ee0e build 2021-07-07 23:42:20 +02:00
marc barbier 7dfe4c2d3f update refacto 2021-07-07 23:36:00 +02:00
marc barbier 7c88e6cf2f refacto + recovery code from uncommited on my old pc 2021-07-07 21:45:33 +02:00
Marc BARBIER 2a6b802bb0 better clean 2021-07-06 16:33:09 +02:00
Marc BARBIER 9480686d71 no ide build 2021-07-06 16:11:29 +02:00
34 changed files with 984 additions and 465 deletions
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ModsListDownloader</name>
<comment>Project ModsListDownloader created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1625690947479</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
@@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.8))
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=/usr/lib/jvm/java-11-graalvm
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true
+24
View File
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>
+4
View File
@@ -0,0 +1,4 @@
libs/*
mcDownloader.jar
objs/*
release-*.zip
+5
View File
@@ -0,0 +1,5 @@
{
"java.project.referencedLibraries": [
"lib/**/*.jar"
]
}
+2
View File
@@ -0,0 +1,2 @@
Class-Path: commons-compress-1.20.jar gson-2.8.7.jar
Main-Class: downloader.Main
Binary file not shown.
Binary file not shown.
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
ALL:
scripts/clean.sh;
scripts/build.sh;
scripts/package.sh;
FAT:
scripts/clean.sh;
scripts/build.sh;
scripts/fatPackage.sh;
CLEAN:
scripts/clean.sh;
RELEASE: FAT
scripts/release.sh;
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
mkdir -p objs
cd src
javac \
-d ../objs\
-cp ../lib/commons-compress-1.20.jar:../lib/gson-2.8.7.jar:../lib/gson-2.8.6.jar:../lib/sqlite-jdbc-3.32.3.2.jar\
downloader/*.java downloader/forgeSvc/*.java downloader/helper/*.java
cd ..
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
ls objs/* > /dev/null 2> /dev/null
HASOBJS=$?
if [ $HASOBJS -eq 0 ]; then
rm objs/* -r
fi
if test -f "mcDownloader.jar"; then
rm mcDownloader.jar
fi
+16
View File
@@ -0,0 +1,16 @@
if test -f "mcDownloader.jar"; then
rm mcDownloader.jar
fi
pwd
LIBS=$( cd objs/ && ls ../lib/*.jar)
echo $LIBS
cd objs
for lib in ${LIBS}; do
jar -xf $lib
done
rm META-INF -r
jar cfm ../mcDownloader.jar ../MANIFEST.MF *
+5
View File
@@ -0,0 +1,5 @@
if test -f "mcDownloader.jar"; then
rm mcDownloader.jar
fi
cd objs && jar cfm ../mcDownloader.jar ../MANIFEST.MF downloader/
+13
View File
@@ -0,0 +1,13 @@
if [ -z "${VER}" ]
then
VER="v0.2"
fi
-rm release-${VER}.zip 2> /dev/null
mv mcDownloader.jar ModPackDl.jar
echo "java -jar ModPackDl.jar --thread 2 -v" > run.sh
echo "java -jar ModPackDl.jar --thread 2 -v" > run.bat
echo "pause" >> run.bat
zip release-${VER}.zip ModPackDl.jar run.sh run.bat
rm run.sh
rm run.bat
rm ModPackDl.jar
@@ -0,0 +1,25 @@
package downloader;
public class CurseForgeModFile extends ProjectInfo {
private int projectID;
private int fileID;
private boolean clientOnly;
public CurseForgeModFile(ProjectInfo pj, int projectID, int fileID, boolean clientOnly) {
this(pj.getSlug(), pj.getName(), pj.getDesc(), projectID, fileID, clientOnly);
}
public CurseForgeModFile(String slug, String name, String desc, int projectID, int fileID, boolean clientOnly) {
super(slug, name, desc);
this.projectID = projectID;
this.fileID = fileID;
this.clientOnly = clientOnly;
}
public int getFileID() {
return this.fileID;
}
public int getProjectID() {
return this.projectID;
}
public boolean isClientOnly() {
return this.clientOnly;
}
}
@@ -6,54 +6,40 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.SortedMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.TreeMap;
import java.util.zip.ZipFile;
public class IntegrityChecker { import downloader.helper.ArchiveHelper;
public String[] fileList; import downloader.helper.SlugHelper;
public SortedMap<Integer, String> installedMods;
public File modsMap; public class CurseUpdateManager {
private ConcurrentHashMap<Integer, String> installedMods;
public CurseUpdateManager()
{
loadModMapFromFile();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public IntegrityChecker() private void loadModMapFromFile() {
{ File modsMapFile = new File("mods/modsMap.sav");
fileList = new File("mods").list(); if(modsMapFile.exists())
modsMap = new File("mods/modsMap.sav");
if(modsMap.exists())
{ {
try { try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(modsMap)); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(modsMapFile));
installedMods = (SortedMap<Integer, String>) ois.readObject(); installedMods = (ConcurrentHashMap<Integer, String>) ois.readObject();
if(installedMods == null)installedMods = new TreeMap<>();
ois.close(); ois.close();
} catch (Exception e) { } catch (Exception e) {
installedMods = new TreeMap<>(); modsMapFile.delete();
modsMap.delete();
}
}else {
try {
modsMap.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }
try { if(installedMods == null)installedMods = new ConcurrentHashMap<>();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(modsMap)); this.updateFile();
oos.writeObject(installedMods);
oos.close();
} catch (IOException e) {
Log.e("SAV", "erreur pas de sauvegarde");
System.exit(1);
}
} }
public boolean checkAndDelete(File modToDownload, int modid) { public boolean checkAndDelete(File modToDownload, int modid) {
String alredyInstalledName = installedMods.get(modid).toLowerCase(); String alredyInstalledName = installedMods.get(modid).toLowerCase();
File alredyInstalledMods= null; File alredyInstalledMods= null;
//on cherche le fichier local affin de ne pas voir d'erreur avec la casse //on cherche le fichier local affin de ne pas voir d'erreur avec la casse
File dir = new File("mods/"); File dir = new File("mods/");
for(String fileName : dir.list()) for(String fileName : dir.list())
@@ -61,8 +47,10 @@ public class IntegrityChecker {
if(fileName.equalsIgnoreCase(alredyInstalledName)) if(fileName.equalsIgnoreCase(alredyInstalledName))
{ {
alredyInstalledMods = new File("mods/"+fileName); alredyInstalledMods = new File("mods/"+fileName);
break;
} }
} }
if(alredyInstalledMods == null) { if(alredyInstalledMods == null) {
Log.e("IntegrityChecker", "alredy installed mod not found ("+alredyInstalledName+")"); Log.e("IntegrityChecker", "alredy installed mod not found ("+alredyInstalledName+")");
installedMods.remove(modid); installedMods.remove(modid);
@@ -71,16 +59,14 @@ public class IntegrityChecker {
} }
if (alredyInstalledMods.exists()) { if (alredyInstalledMods.exists()) {
try { //we only check if the jar file still works
//si sa balance une exception sa veut dire que le jar n'est pas lisible if(!ArchiveHelper.checkJarIntegrity(alredyInstalledMods)) {
new ZipFile(alredyInstalledMods).close();
} catch (IOException e) {
Log.i("integrityChecker","Corruption detected redownloading");
alredyInstalledMods.delete(); alredyInstalledMods.delete();
installedMods.remove(modid); installedMods.remove(modid);
updateFile(); updateFile();
return false; return false;
} }
if(!modToDownload.getAbsolutePath().equalsIgnoreCase(alredyInstalledMods.getAbsolutePath())) if(!modToDownload.getAbsolutePath().equalsIgnoreCase(alredyInstalledMods.getAbsolutePath()))
{ {
alredyInstalledMods.delete(); alredyInstalledMods.delete();
@@ -95,37 +81,25 @@ public class IntegrityChecker {
{ {
installedMods.put(modid, modToDownload.getName()); installedMods.put(modid, modToDownload.getName());
updateFile(); updateFile();
Log.i("interessting", modToDownload.getName()); Log.i("CurseUpdater","existing file detected adding it to the register: " + modToDownload.getName());
}
}
return false;
}
public boolean checkAndDelete(File modToDownload, String slug) {
if (modToDownload.exists()) {
try {
//si sa balance une exception sa veut dire que le jar n'est pas lisible
new ZipFile(modToDownload).close();
} catch (IOException e) {
Log.i("integrityChecker","Corruption detected redownloading");
modToDownload.delete();
return false;
}
for (String s : fileList) {
if (s.contains(slug)) {
if (!modToDownload.getName().contains(s)) {
new File(s).delete();
Log.i("integrityChecker","Corruption detected redownloading");
return false;
}
return true; return true;
} }
} }
return false; return false;
}
/**
* @return true == file ok
*/
public boolean checkAndDelete(File modToDownload, String slug) {
if (modToDownload.exists()) {
if (ArchiveHelper.checkJarIntegrity(modToDownload)) {
return true;
} else {
SlugHelper.deleteBySlug(slug);
return false;
}
} }
return false; return false;
} }
@@ -135,26 +109,27 @@ public class IntegrityChecker {
* @param fileName * @param fileName
* @param modID * @param modID
*/ */
public void addModsToTheList(String fileName,int modID) public synchronized void addModsToTheList(String fileName,int modID)
{ {
installedMods.put(modID, fileName); installedMods.put(modID, fileName);
updateFile();
} }
public boolean isModIdKnown(int modId) public synchronized boolean isModIdKnown(int modId)
{ {
return installedMods.get(modId) != null; return installedMods.get(modId) != null;
} }
private void updateFile() public synchronized void updateFile()
{ {
File modsMap = new File("mods/modsMap.sav");
try { try {
modsMap.delete(); if(modsMap.exists())modsMap.delete();
//modsMap.createNewFile();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(modsMap)); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(modsMap));
oos.writeObject(installedMods); oos.writeObject(installedMods);
oos.close(); oos.close();
} catch (IOException e) {} } catch (IOException e) {
Log.e("SAV", "erreur pas de sauvegarde");
}
} }
} }
@@ -8,20 +8,12 @@ import java.sql.SQLException;
public class DBConnector { public class DBConnector {
private Connection conn; private Connection conn;
/**
* Connect to a sample database
*
* @throws SQLException
*/
public void connect(String dbFile) throws SQLException { public void connect(String dbFile) throws SQLException {
conn = null; this.conn = null;
try { try {
// db parameters
String url = "jdbc:sqlite:" + dbFile; String url = "jdbc:sqlite:" + dbFile;
Log.i("DB",url); Log.i("DB", url);
// create a connection to the database this.conn = DriverManager.getConnection(url);
conn = DriverManager.getConnection(url);
} catch (SQLException e) { } catch (SQLException e) {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
throw e; throw e;
@@ -29,15 +21,15 @@ public class DBConnector {
} }
public void close() throws SQLException { public void close() throws SQLException {
conn.close(); this.conn.close();
} }
public ResultSet executeRequest(String sql) { public ResultSet executeRequest(String sql) {
try { try {
return conn.createStatement().executeQuery(sql); return this.conn.createStatement().executeQuery(sql);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
}
return null; return null;
} }
}
} }
@@ -0,0 +1,107 @@
package downloader;
import java.io.File;
import java.net.MalformedURLException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import com.google.gson.Gson;
import downloader.forgeSvc.ForgeSvcEntry;
import downloader.forgeSvc.ForgeSvcFile;
import downloader.helper.HttpHelper;
public class Database {
private DBConnector connector;
private Gson gson;
private static final String ME = "Db";
public Database() {
try {
//work around to avoid
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e1) {
Log.e(ME, "Error sqLite was not found");
System.exit(1);
}
this.connector = new DBConnector();
try {
this.connector.connect((new File("database.dat")).getAbsolutePath());
} catch (SQLException e) {
//database hs
System.exit(1);
}
this.gson = new Gson();
}
private int findProjectBySlug(String slug, int ptype) {
int pjId = -1;
ResultSet rs = this.connector.executeRequest("select projectid from projects where type =" + ptype + " and slug LIKE \"" + slug.trim().toLowerCase() + "\"");
try {
if (rs.next()) {
pjId = rs.getInt("projectid");
} else {
Log.e(ME, "not found " + slug);
return -1;
}
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
return pjId;
}
public int findModBySlug(String slug) {
return findProjectBySlug(slug, 0);
}
public ProjectInfo getProjectInfo(int projectId) {
ResultSet rs = this.connector.executeRequest(
"select slug, name, description from projects where projectid = " + projectId + " and type = 0");
try {
if (rs.next())
return new ProjectInfo(rs.getString("slug"), rs.getString("name"), rs.getString("description"));
} catch (SQLException sQLException) {}
return null;
}
public ForgeSvcFile fetchMod(ProjectInfo pj, int modID) {
CurseForgeModFile modfile = new CurseForgeModFile(pj, modID, -1, false);
return getLastestFile(modfile);
}
public ForgeSvcFile getLastestFile(CurseForgeModFile mod) {
String jsonProject;
String projectUrl = "https://addons-ecs.forgesvc.net/api/v2/addon/" + mod.getProjectID();
try {
jsonProject = HttpHelper.readStringFromUrl(projectUrl);
if (jsonProject.equals("error"))
return null;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
ForgeSvcEntry entry = this.gson.fromJson(jsonProject, ForgeSvcEntry.class);
ForgeSvcFile[] arrayOfForgeSvcFile = fileterGameVersion(entry.getFiles());
if(arrayOfForgeSvcFile.length == 0) return null;
//on par du pricipe qu'un id plus élevé => version plus récente
ForgeSvcFile latest = arrayOfForgeSvcFile[0];
for (int i = 1; i < arrayOfForgeSvcFile.length; i++) {
if( arrayOfForgeSvcFile[i].getProjectFileId() > latest.getProjectFileId() ) {
latest = arrayOfForgeSvcFile[i];
}
}
return latest;
}
private ForgeSvcFile[] fileterGameVersion(ForgeSvcFile[] arrayOfForgeSvcFile) {
return Arrays.stream(arrayOfForgeSvcFile).filter(x -> x.getGameVersion().equals(Main.mcVersion)).toArray(ForgeSvcFile[]::new);
}
}
@@ -0,0 +1,100 @@
package downloader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import downloader.helper.ArchiveHelper;
import downloader.helper.HttpHelper;
public class DatabaseVersionManager {
private String version;
private static final String ME = "DBUpdater";
public DatabaseVersionManager() {
try {
this.version = fetchVersionFromFile();
} catch (FileNotFoundException e) {
this.version = null;
}
}
public void updateIfNeeded() {
String latestVersion = fetchLatestVersion();
if( version == null || !latestVersion.equals(version) ) {
Log.i(ME, "new dbVersion avaliable downloading...");
downloadDatabase(latestVersion);
saveDbVersion(latestVersion);
} else {
Log.i(ME, "update to Date");
}
}
private void saveDbVersion(String latestVersion) {
File versionFile = new File("dbVersion");
PrintWriter out;
try {
out = new PrintWriter(new FileWriter(versionFile));
out.println(latestVersion);
out.close();
} catch (IOException e) {}
}
private void downloadDatabase(String dbVersion) {
Log.i(ME, "fetching=" + "http://files.mcdex.net/data/mcdex-v5-" + dbVersion + ".dat.bz2");
File archive;
try {
archive = HttpHelper.readFileFromUrl("http://files.mcdex.net/data/mcdex-v5-" + dbVersion + ".dat.bz2");
} catch (MalformedURLException e) {
Log.e(ME, "Error invalid database download url");
System.exit(1);
//utile pour le lint
return;
}
Log.i(ME, "download finished");
Log.i(ME, "decompressing db");
try {
ArchiveHelper.decompressBz2(archive, "database.dat");
archive.delete();
} catch (IOException e) {
Log.e(ME, "[ERROR]cannot extract database");
if(archive.exists()) archive.delete();
System.exit(1);
}
}
private String fetchLatestVersion() {
try {
return HttpHelper.readStringFromUrl("http://files.mcdex.net/data/latest.v5");
} catch (MalformedURLException e) {
//erreur critique il ne faut pas continuer
e.printStackTrace();
System.exit(1);
}
return null;
}
private static String fetchVersionFromFile() throws FileNotFoundException {
File versionFile = new File("dbVersion");
if( versionFile.exists()) {
BufferedReader bfr = new BufferedReader(new FileReader(versionFile));
try {
String version = bfr.readLine();
bfr.close();
return version;
} catch (IOException e) {
//si on peut pas lire le fichier on le suprime
versionFile.delete();
return null;
}
}
throw new FileNotFoundException();
}
}
@@ -0,0 +1,26 @@
package downloader;
import java.io.File;
import downloader.helper.ArchiveHelper;
import downloader.helper.SlugHelper;
public class DirectUpdateManager {
/**
* @param filename
* @param slug
* @return upToDate
*/
public boolean checkAndDelete(String filename, String slug) {
File mod = new File("mods/"+filename.toLowerCase());
if (!mod.exists()) {
SlugHelper.deleteBySlug(slug);
return false;
} else {
return ArchiveHelper.checkJarIntegrity(mod);
}
}
}
@@ -0,0 +1,34 @@
package downloader;
import java.io.PrintStream;
public class Log {
private Log() {}
private static String staticLine = "";
private static PrintStream lastStream = System.out;
public static void e(String who, String msg) {
printNonStatic("[ERROR]" + who + " : " + msg, System.err);
}
public static void w(String who, String msg) {
printNonStatic("[WARN]" + who + " : " + msg, System.out);
}
public static void i(String who, String msg) {
if(Main.verbose) printNonStatic("[INFO]" + who + " : " + msg, System.out);
}
private static void printNonStatic(String line, PrintStream stream) {
//erase last stream since we used \r
lastStream.print("");
stream.println(line);
stream.print(staticLine + " \r");
lastStream = stream;
}
public static void setStaticPrint(String staticString) {
staticLine = staticString;
System.out.print(staticString + " \r");
}
}
+123
View File
@@ -0,0 +1,123 @@
package downloader;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Iterator;
public class Main {
public static boolean verbose;
public static Integer threadNb;
public static String mcVersion;
public static void main(String[] args) {
if(mcVersion == null) {
mcVersion = "1.12.2";
}
else {
if(!isVersionValid()) {
Log.e("main", "the version number provided is invalid");
System.exit(1);
}
}
checkModsDirectory();
new DatabaseVersionManager().updateIfNeeded();
interpretArgs(args);
//no threading option called => only one thread will be used
if( threadNb == null)threadNb = 1;
Log.i("Main", "Running on " + threadNb + " thread");
new ModUpdater().update();
}
public static void checkModsDirectory() {
File modDir = new File("mods");
if(!modDir.exists()) {
try {
Files.createDirectories(Paths.get("mods"));
} catch (IOException e) {
Log.e("Main","could not create folder");
System.exit(0);
}
}
}
private static void interpretArgs(String[] args) {
Iterator<String> it = Arrays.asList(args).iterator();
final int cores = Runtime.getRuntime().availableProcessors();
while (it.hasNext()) {
String cmd = it.next();
switch (cmd) {
case "-t":
Log.w("main", "Warning using -t option can lead to corruption during download if you have a lot of cores or a slow internet");
if (threadNb != null) {
Log.e("main", "error conflicting arguments --thread and -t");
System.exit(1);
}
if (cores <= 0) {
Log.i("main","java think you have no cpu core... sooo lets go for 2");
threadNb = Integer.valueOf(2);
break;
}
Log.i("main", "running on " + cores + " thread");
threadNb = Integer.valueOf(cores);
break;
case "-v":
verbose = true;
break;
case "-version":
checkNext(it);
mcVersion = it.next();
break;
case "--thread":
if (threadNb != null) {
Log.e("main", "error conflicting arguments --thread and -t");
System.exit(1);
}
checkNext(it);
String threadNumber = it.next();
if (threadNumber.matches("[0-9]*")) {
threadNb = Integer.valueOf(Integer.parseInt(threadNumber));
break;
}
Log.e("main","arguments invalid please refer to --help");
System.exit(1);
break;
case "--help":
Log.i("main", "use --help to see this help\nuse -v to see verbose\nuse --threads to specify the number of threads\nuse -t to set the number of thread automaticaly");
System.exit(0);
break;
default:
Log.e("main", "unknown args " + cmd + "\nsee --help for help");
System.exit(1);
}
}
}
private static boolean isVersionValid() {
switch(mcVersion.split(".").length) {
case 2:
return mcVersion.matches("[0-9]*\\.[0-9]*");
case 3:
return mcVersion.matches("[0-9]*\\.[0-9]*\\.[0-9]*");
default:
return false;
}
}
private static void checkNext(Iterator<String> it) {
if (!it.hasNext()) {
Log.e("main", "arguments invalid please refer to --help");
System.exit(1);
}
}
}
@@ -0,0 +1,241 @@
package downloader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import downloader.forgeSvc.ForgeSvcFile;
import downloader.helper.ArchiveHelper;
import downloader.helper.HttpHelper;
public class ModUpdater {
private DirectUpdateManager directUpdateManager;
private CurseUpdateManager curseUpdateManager;
private Database db;
private static final String ME = "ModUpdater";
public ModUpdater() {
this.db = new Database();
this.directUpdateManager = new DirectUpdateManager();
this.curseUpdateManager = new CurseUpdateManager();
}
public void update() {
File modsList = new File("modpack.txt");
if(!(modsList.exists() && modsList.isFile())) {
Log.e(ME, "[ERROR]no mod file found exiting...");
System.exit(1);
}
//parse and download
startProcessingThreads(modsList);
checkForFailures();
Log.i(ME, "finished");
curseUpdateManager.updateFile();
}
private void startProcessingThreads(File modsList) {
List<Thread> threads = new ArrayList<>(Main.threadNb);
try {
BufferedReader in = new BufferedReader(new FileReader(modsList));
while (in.ready()) {
String line = in.readLine();
if (!isAComment(line)) {
Thread t = new UpdaterThread(line, db, directUpdateManager, curseUpdateManager, threads);
t.start();
threads.add(t);
}
while(Main.threadNb >= threads.size()) {
threadSleep();
}
}
in.close();
} catch( IOException e ) {
e.printStackTrace();
System.exit(1);
}
waitThreadsEnd(threads);
}
private void checkForFailures() {
if(! UpdaterThread.failedLines.isEmpty()) {
List<String> failures = new ArrayList<>(UpdaterThread.failedLines);
UpdaterThread.failedLines.clear();
Log.e(ME, "filed to download " + failures.size());
Log.e(ME, "Retrying but slower");
for(String line : failures) {
Thread t = new UpdaterThread(line, db, directUpdateManager, curseUpdateManager, null);
t.start();
try {
t.join();
} catch (InterruptedException e) {}
}
if(! UpdaterThread.failedLines.isEmpty()) {
Log.e(ME, "could not download the following mods : ");
for(String s: failures) {
Log.e(ME, " " + s);
}
}
}
}
private void waitThreadsEnd(List<Thread> threads) {
while( !threads.isEmpty() ) {
threadSleep();
}
}
private void threadSleep() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
}
public static boolean isAComment(String line)
{
return line.startsWith("//");
}
}
final class UpdaterThread extends Thread {
private final String line;
private final Database db;
private final DirectUpdateManager directUpdateManager;
private final CurseUpdateManager curseUpdateManager;
private final List<Thread> threads;
private static final String ME = "ModUpdaterThread";
protected static final List<String> failedLines = new ArrayList<>();
public UpdaterThread(String line, Database db, DirectUpdateManager directUpdateManager, CurseUpdateManager curseUpdateManager, List<Thread> threads) {
super(line);
this.line = line;
this.db = db;
this.directUpdateManager = directUpdateManager;
this.curseUpdateManager = curseUpdateManager;
this.threads = threads;
}
@Override
public void run() {
try {
//used for post download checks
File downloadedFile = null;
if(line.startsWith("direct=") && line.contains(";") && line.contains("@"))
{
downloadedFile = handleDirectDownload(line);
} else if (line.startsWith("del=")) {
String[] delete = line.split("del=");
if(new File("mods/" + delete[1]).delete()) {
Log.i(ME, "Successfully removed " + delete[1]);
}
}
else {
if (line.split("/").length >= 5 && line.contains("curseforge")) {
downloadedFile = handleCurseDownload(line);
} else {
Log.e(ME, "unrecognized line: " + line);
}
}
if(downloadedFile != null && !ArchiveHelper.checkJarIntegrity(downloadedFile)) {
downloadedFile.delete();
failedLines.add(line);
}
} catch(Exception e) { e.printStackTrace(); }
super.run();
//on se retire de la pool d'execution
if(this.threads != null)this.threads.remove(this);
}
private File handleDirectDownload(String line) {
String url = line.replaceFirst("direct=.*@", "");
String filename=extractNameFromLink(line);
//le slug est une nom de mods qui se trouve dans le nom du fichier
String slug = extractSlugFromLink(line);
//on check si le mods est pas déja installé et si il est a jours
boolean upToDate = directUpdateManager.checkAndDelete(filename, slug);
if(!upToDate)
{
Log.i(ME,"downloading "+ filename);
try {
Log.i(ME,"done");
return HttpHelper.readFileFromUrlToFolder(url,"mods",filename);
} catch (MalformedURLException e) {
Log.e(ME, "could not update mod, error while downloading");
}
}
return null;
}
private File handleCurseDownload(String line) {
String name = line.split("/")[5];
int modID = db.findModBySlug(name);
ProjectInfo pj = db.getProjectInfo(modID);
ForgeSvcFile svc = db.fetchMod(pj, modID);
if (svc != null) {
try {
boolean upToDate;
String downloadUrl = svc.getDownloadUrl(modID);
Log.i("MOD", "checking " + pj.getName().replace(" ", "-"));
if (this.curseUpdateManager.isModIdKnown(modID)) {
Log.i("DB", "found " + name);
upToDate = this.curseUpdateManager.checkAndDelete(new File("mods/" + HttpHelper.getFileNameFromURL(downloadUrl)), modID);
}
else {
Log.i("DB", "NEW MOD DETECTED " + modID);
upToDate = this.curseUpdateManager.checkAndDelete(new File("mods/" + HttpHelper.getFileNameFromURL(downloadUrl)), pj.getSlug());
if(upToDate) {
Log.i("who", "file found");
this.curseUpdateManager.addModsToTheList("mods/" + HttpHelper.getFileNameFromURL(downloadUrl), modID);
}
}
if (!upToDate) {
Log.i("MOD", "downloading " + pj.getName().replace(" ", "-"));
File downloaded = HttpHelper.readFileFromUrlToFolder(downloadUrl, "mods");
Log.i("MOD", "download finished");
if (!this.curseUpdateManager.isModIdKnown(modID)) {
this.curseUpdateManager.addModsToTheList(HttpHelper.getFileNameFromURL(downloadUrl), modID);
Log.i("DB", "added a mod to the registry");
}
return downloaded;
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
} else {
Log.e("DB", "no file in server");
}
return null;
}
private static String extractNameFromLink(String line) {
char[] chars = new char[line.indexOf("@")-line.indexOf(";")];
line.getChars(line.indexOf(";")+1, line.indexOf("@"), chars, 0);
return new String(chars);
}
private static String extractSlugFromLink(String line) {
char[] chars = new char[line.length()-line.indexOf(";")-"direct=".length()+1];
line.getChars("direct=".length(), line.indexOf(";"), chars, 0);
return new String(chars);
}
}
@@ -1,24 +1,27 @@
package downloader; package downloader;
public class ProjectInfo { public class ProjectInfo {
private String slug, name, desc; private String slug;
private String name;
private String desc;
public ProjectInfo(String slug, String name, String desc) { public ProjectInfo(String slug, String name, String desc) {
super();
this.slug = slug; this.slug = slug;
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
} }
public String getDesc() { public String getDesc() {
return desc; return this.desc;
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public String getSlug() { public String getSlug() {
return slug; return this.slug;
} }
} }
@@ -4,6 +4,6 @@ public class ForgeSvcEntry {
private ForgeSvcFile[] gameVersionLatestFiles; private ForgeSvcFile[] gameVersionLatestFiles;
public ForgeSvcFile[] getFiles() { public ForgeSvcFile[] getFiles() {
return gameVersionLatestFiles; return this.gameVersionLatestFiles;
} }
} }
@@ -2,7 +2,7 @@ package downloader.forgeSvc;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import downloader.HttpHelper; import downloader.helper.HttpHelper;
public class ForgeSvcFile { public class ForgeSvcFile {
private String gameVersion; private String gameVersion;
@@ -11,21 +11,22 @@ public class ForgeSvcFile {
private String projectFileName; private String projectFileName;
public String getGameVersion() { public String getGameVersion() {
return gameVersion; return this.gameVersion;
} }
public int getFileType() { public int getFileType() {
return fileType; return this.fileType;
} }
public int getProjectFileId() { public int getProjectFileId() {
return projectFileId; return this.projectFileId;
} }
public String getProjectFileName() { public String getProjectFileName() {
return projectFileName; return this.projectFileName;
} }
public String getDownloadUrl(int modID) throws MalformedURLException { public String getDownloadUrl(int modID) throws MalformedURLException {
return HttpHelper.readStringFromUrl("https://addons-ecs.forgesvc.net/api/v2/addon/"+modID+"/file/"+projectFileId+"/download-url"); return HttpHelper.readStringFromUrl("https://addons-ecs.forgesvc.net/api/v2/addon/" + modID + "/file/" + this.projectFileId + "/download-url");
} }
} }
@@ -0,0 +1,42 @@
package downloader.helper;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarFile;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;
import downloader.Log;
public class ArchiveHelper {
private ArchiveHelper(){}
public static File decompressBz2(File inputFile, String outputFile) throws IOException {
BZip2CompressorInputStream input = new BZip2CompressorInputStream(
new BufferedInputStream(new FileInputStream(inputFile)));
File decompressedFile = new File(outputFile);
FileOutputStream output = new FileOutputStream(decompressedFile);
IOUtils.copy(input, output);
return decompressedFile;
}
/**
* @param mod
* @return true = fichier bon
*/
public static boolean checkJarIntegrity(File mod) {
try {
//si sa balance une exception sa veut dire que le jar n'est pas lisible
new JarFile(mod).close();
} catch (IOException e) {
Log.i("integrityChecker","Corruption detected redownloading");
mod.delete();
return false;
}
return true;
}
}
@@ -1,4 +1,4 @@
package downloader; package downloader.helper;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -10,9 +10,13 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Locale;
import downloader.Log;
import downloader.Main;
public class HttpHelper { public class HttpHelper {
private HttpHelper() {}
public static String readStringFromUrl(String urlToFetch) throws MalformedURLException { public static String readStringFromUrl(String urlToFetch) throws MalformedURLException {
URL url = new URL(urlToFetch); URL url = new URL(urlToFetch);
@@ -39,8 +43,7 @@ public class HttpHelper {
} }
} }
} catch (IOException e) { } catch (IOException e) {}
}
return str; return str;
} }
@@ -89,13 +92,11 @@ public class HttpHelper {
} }
File downloadingFile = destination; File downloadingFile = destination;
System.out.println(downloadingFile.getAbsolutePath());
if (downloadingFile.exists()) { if (downloadingFile.exists()) {
return downloadingFile; return downloadingFile;
} else { } else {
try { try {
System.out.println(downloadingFile);
downloadingFile.createNewFile(); downloadingFile.createNewFile();
} catch (IOException e) { } catch (IOException e) {
Log.e("HTTPHelper","permission error could not write file"); Log.e("HTTPHelper","permission error could not write file");
@@ -112,8 +113,8 @@ public class HttpHelper {
// imposible vu qu'on l'a crée precedament // imposible vu qu'on l'a crée precedament
} }
double start = System.currentTimeMillis();
try (InputStream in = con.getInputStream()) { try (InputStream in = con.getInputStream()) {
//int totalRead = 0;
// on lit par tranche de 4mo // on lit par tranche de 4mo
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
@@ -121,19 +122,52 @@ public class HttpHelper {
int bytesRead = in.read(buffer); int bytesRead = in.read(buffer);
if (bytesRead < 0) if (bytesRead < 0)
break; break;
//totalRead += bytesRead;
double elapsed = ( System.currentTimeMillis() - start ) / 1000;
if(elapsed != 0) {
long estimatedBandwith = (long) (bytesRead / elapsed);
//display the estimate
Log.setStaticPrint("estimated bandwidth :" + formatBandwidth(estimatedBandwith * Main.threadNb));
start = System.currentTimeMillis();
}
downloadingWriter.write(buffer, 0, bytesRead); downloadingWriter.write(buffer, 0, bytesRead);
//TODO afficher cette valeur si on a un ui
//System.out.println("\r" + totalRead);
} }
downloadingWriter.close(); downloadingWriter.close();
return downloadingFile; return downloadingFile;
} catch (IOException e) { } catch (IOException e) {}
}
return null; return null;
} }
/**
*
* @param estimatedBandwith in o/s
* @return
*/
private static String formatBandwidth(long estimatedBandwith) {
//is ko/s
if(estimatedBandwith > 1000) {
//is mo/s
if(estimatedBandwith > 1000 * 1000) {
return String.valueOf(estimatedBandwith/ (1000 * 1000)) + "M" + getLocalizedByte() + "/s";
} else {
return String.valueOf(estimatedBandwith/ 1000) + "K" + getLocalizedByte() + "/s";
}
} else {
return String.valueOf(estimatedBandwith) + getLocalizedByte() + "/s";
}
}
private static String getLocalizedByte() {
Locale l = Locale.getDefault();
if (l.equals(Locale.FRANCE) | l.equals(Locale.FRENCH)) {
return "O";
} else {
return "B";
}
}
public static String getFileNameFromURL(String url) public static String getFileNameFromURL(String url)
{ {
String[] urlsplit = url.split("/"); String[] urlsplit = url.split("/");
@@ -0,0 +1,16 @@
package downloader.helper;
import java.io.File;
public class SlugHelper {
public static void deleteBySlug(String slug) {
File modFolder = new File("mods");
File[] mods = modFolder.listFiles();
for( File mod : mods) {
if(mod.getName().toLowerCase().contains((slug.toLowerCase()))) {
mod.delete();
}
}
}
}
-30
View File
@@ -1,30 +0,0 @@
package downloader;
public class CurseForgeModFile extends ProjectInfo{
private int projectID;
private int fileID;
private boolean clientOnly;
public CurseForgeModFile(ProjectInfo pj,int projectID,int fileID,boolean clientOnly)
{
this(pj.getSlug(),pj.getName(),pj.getDesc(),projectID,fileID,clientOnly);
}
public CurseForgeModFile(String slug, String name, String desc,int projectID,int fileID,boolean clientOnly) {
super(slug, name, desc);
this.projectID=projectID;
this.fileID=fileID;
this.clientOnly=clientOnly;
}
public int getFileID() {
return fileID;
}
public int getProjectID() {
return projectID;
}
public boolean isClientOnly() {
return clientOnly;
}
}
-226
View File
@@ -1,226 +0,0 @@
package downloader;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;
import com.google.gson.Gson;
import downloader.forgeSvc.ForgeSvcEntry;
import downloader.forgeSvc.ForgeSvcFile;
public class Database {
String version;
DBConnector connector;
Gson gson;
IntegrityChecker integrityChecker;
File dbVer;
public Database() {
dbVer = new File("dbVersion");
if (dbVer.exists()) {
try {
BufferedReader bfr = new BufferedReader(new FileReader(dbVer));
this.version = bfr.readLine();
bfr.close();
connector = new DBConnector();
connector.connect(new File("database.dat").getAbsolutePath());
} catch (IOException | SQLException e) {
dbVer.delete();
version = "";
}
} else {
version = "";
}
gson = new Gson();
integrityChecker = new IntegrityChecker();
}
public void updateDatabase() {
try {
String dbVersion = HttpHelper.readStringFromUrl("http://files.mcdex.net/data/latest.v5");
if (dbVersion.equals(version)) {
Log.i("DB", "alredy up to date");
return;
}
if (dbVersion.equals("error")) {
Log.i("DB", "an error ocured");
return;
}
Log.i("DB", "newer version found");
if (!this.version.isEmpty()) {
Log.i("DB", "current=" + this.version + " remote=" + dbVersion);
} else {
Log.i("DB", "new=" + dbVersion);
}
Log.i("DB", "fetching=" + "http://files.mcdex.net/data/mcdex-v5-" + dbVersion + ".dat.bz2");
File archive = HttpHelper.readFileFromUrl("http://files.mcdex.net/data/mcdex-v5-" + dbVersion + ".dat.bz2");
Log.i("DB", "download finished");
Log.i("DB", "decompressing db");
File decompressedDatabase;
try {
decompressedDatabase = decompressBz2(archive, "database.dat");
} catch (IOException e) {
Log.i("DB", "cannot extract database");
return;
}
Log.i("DB", "done");
Log.i("DB", "loading the database");
connector = new DBConnector();
try {
connector.connect(decompressedDatabase.getAbsolutePath());
} catch (SQLException e) {
return;
}
Log.i("DB", "database loaded");
this.version = dbVersion;
Log.i("DB", "saving db data");
dbVer.delete();
try {
dbVer.createNewFile();
PrintWriter p = new PrintWriter(dbVer);
p.print(version);
p.close();
} catch (Exception e) {
Log.e("DB", "failed to save db");
}
} catch (MalformedURLException e) {
Log.i("DB", "database link is dead");
System.exit(1);
}
}
private File decompressBz2(File inputFile, String outputFile) throws IOException {
BZip2CompressorInputStream input = new BZip2CompressorInputStream(
new BufferedInputStream(new FileInputStream(inputFile)));
File decompressedFile = new File(outputFile);
FileOutputStream output = new FileOutputStream(decompressedFile);
IOUtils.copy(input, output);
return decompressedFile;
}
private int findProjectBySlug(String slug, int ptype) {
int modID = -1;
ResultSet rs = connector.executeRequest("select projectid from projects where type =" + ptype + " and slug =\""
+ slug.trim().toLowerCase() + "\"");
try {
if (rs.next()) {
modID = rs.getInt("projectid");
} else {
Log.e("DB", "not found " + slug);
return -1;
}
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
return modID;
}
private int findModBySlug(String slug) {
return findProjectBySlug(slug, 0);
}
private ProjectInfo getProjectInfo(int projectId) {
ResultSet rs = connector.executeRequest(
"select slug, name, description from projects where projectid = " + projectId + " and type = 0");
try {
if (rs.next()) {
return new ProjectInfo(rs.getString("slug"), rs.getString("name"), rs.getString("description"));
}
} catch (SQLException e) {
}
return null;
}
public boolean fetchMod(String string) {
String name = string.split("/")[5];
int modID = findModBySlug(name);
if (modID == -1) {
Log.e("DB", "could not find mod id");
return false;
}
ProjectInfo pj = getProjectInfo(modID);
if (pj == null)
return false;
CurseForgeModFile modfile = new CurseForgeModFile(pj, modID, -1, false);
ForgeSvcFile file = getLastestFile("1.12.2", modfile);
if (file != null) {
try {
String downloadUrl = file.getDownloadUrl(modID);
Log.i("MOD", "checking " + pj.getName().replace(" ", "-"));
// si on connais le mod alors on se base si son fichier sinon on essay de le
// trouver
boolean upToDate;
if (integrityChecker.isModIdKnown(modID)) {
Log.i("DB", "found");
upToDate = integrityChecker
.checkAndDelete(new File("mods/" + HttpHelper.getFileNameFromURL(downloadUrl)), modID);
} else {
Log.i("DB", "NEW MOD DETECTED "+modID);
upToDate = integrityChecker.checkAndDelete(
new File("mods/" + HttpHelper.getFileNameFromURL(downloadUrl)), pj.getSlug());
}
if (!upToDate) {
// on remplace les espace par des tiret pour eviter toute confusion
Log.i("MOD", "downloading " + pj.getName().replace(" ", "-"));
HttpHelper.readFileFromUrlToFolder(downloadUrl, "mods");
Log.i("MOD", "download finished");
if (!integrityChecker.isModIdKnown(modID)) {
integrityChecker.addModsToTheList(HttpHelper.getFileNameFromURL(downloadUrl), modID);
Log.i("DB", "added a mod to the registry");
}
}
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
}
} else {
Log.e("DB", "no file in server");
}
return false;
}
public ForgeSvcFile getLastestFile(String minecraftVer, CurseForgeModFile mod) {
String projectUrl = "https://addons-ecs.forgesvc.net/api/v2/addon/" + mod.getProjectID();
String jsonProject;
try {
jsonProject = HttpHelper.readStringFromUrl(projectUrl);
if (jsonProject.equals("error"))
return null;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
ForgeSvcEntry entry = gson.fromJson(jsonProject, ForgeSvcEntry.class);
for (ForgeSvcFile f : entry.getFiles()) {
if (f.getGameVersion().equals(minecraftVer)) {
return f;
}
}
return null;
}
}
-12
View File
@@ -1,12 +0,0 @@
package downloader;
public class Log {
public static void e(String who,String msg)
{
System.err.println(who + " : "+msg);
}
public static void i(String who,String msg)
{
System.out.println(who +" : "+msg);
}
}
-78
View File
@@ -1,78 +0,0 @@
package downloader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws FileNotFoundException, IOException, URISyntaxException {
try {
Files.createDirectories(Paths.get("mods"));
} catch (IOException e) {
Log.e("HTTPHelper","could not create folder");
System.exit(0);
}
IntegrityChecker updateManager = new IntegrityChecker();
Database db = new Database();
db.updateDatabase();
File f;
if(args.length == 0)f = new File("modpack.txt");
else f = new File(args[0]);
BufferedReader in = new BufferedReader(new FileReader(f));
while (in.ready()) {
String line = in.readLine();
if (!isAComment(line)) {
if(line.startsWith("direct="))
{
String url = line.replaceFirst("direct=.*@", "");
String filename=extractNameFromLink(line);
//le slug est une nom de mods qui se trouve dans le nom du fichier
String slug = extractSlugFromLink(line);
//on check si le mods est pas déja installé et si il est a jours
boolean upToDate = updateManager.checkAndDelete(new File("mods/"+filename), slug);
if(!upToDate)
{
Log.i("main","downloading "+ filename);
HttpHelper.readFileFromUrlToFolder(url,"mods",filename);
Log.i("main","done");
}
}else {
if (line.split("/").length >= 5 && !db.fetchMod(line)) {
Log.e("main","error could not get " + line);
}
}
}
}
in.close();
Log.i("Main", "finished");
}
private static String extractSlugFromLink(String line) {
char[] chars = new char[line.length()-line.indexOf(";")-"direct=".length()+1];
line.getChars("direct=".length(), line.indexOf(";"), chars, 0);
return new String(chars);
}
private static String extractNameFromLink(String line) {
char[] chars = new char[line.indexOf("@")-line.indexOf(";")];
line.getChars(line.indexOf(";")+1, line.indexOf("@"), chars, 0);
return new String(chars);
}
public static boolean isAComment(String line)
{
return line.startsWith("//");
}
}