This repository has been archived by the owner on Mar 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
234 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
# InstanceSync | ||
Git hook to allow for modpack version control without moving around jar files | ||
Git hook to allow for modpack version control without moving around jar files. | ||
**Requires gson**. | ||
|
||
## Using | ||
|
||
WIP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package vazkii.instancesync; | ||
|
||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.InputStream; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import vazkii.instancesync.Instance.Addon; | ||
import vazkii.instancesync.Instance.Addon.AddonFile; | ||
|
||
public class DownloadManager { | ||
|
||
private final File modsDir; | ||
|
||
private List<String> acceptableFilenames = new LinkedList<>(); | ||
private ExecutorService executor; | ||
private int downloadCount; | ||
|
||
public DownloadManager(File modsDir) { | ||
this.modsDir = modsDir; | ||
} | ||
|
||
public void downloadInstance(Instance instance) { | ||
executor = Executors.newFixedThreadPool(10); | ||
|
||
System.out.println("Downloading any missing mods"); | ||
long time = System.currentTimeMillis(); | ||
|
||
for(Addon a : instance.installedAddons) | ||
downloadAddonIfNeeded(a); | ||
|
||
if(downloadCount == 0) { | ||
System.out.println("No mods need to be downloaded, yay!"); | ||
} else try { | ||
executor.shutdown(); | ||
executor.awaitTermination(1, TimeUnit.DAYS); | ||
|
||
float secs = (float) (System.currentTimeMillis() - time) / 1000F; | ||
System.out.printf("Finished downloading %d mods (Took %.2fs)%n%n", downloadCount, secs); | ||
} catch (InterruptedException e) { | ||
System.out.println("Downloads were interrupted!"); | ||
e.printStackTrace(); | ||
} | ||
|
||
deleteRemovedMods(); | ||
} | ||
|
||
private void downloadAddonIfNeeded(Addon addon) { | ||
AddonFile file = addon.installedFile; | ||
if(file == null) | ||
return; | ||
|
||
acceptableFilenames.add(file.fileNameOnDisk); | ||
|
||
File modFile = new File(modsDir, file.fileNameOnDisk); | ||
if(!modExists(modFile)) | ||
download(modFile, file.downloadUrl); | ||
} | ||
|
||
private void download(final File target, final String downloadUrl) { | ||
Runnable run = () -> { | ||
String name = target.getName(); | ||
|
||
try { | ||
System.out.println("Downloading " + name); | ||
long time = System.currentTimeMillis(); | ||
|
||
URL url = new URL(downloadUrl); | ||
FileOutputStream out = new FileOutputStream(target); | ||
|
||
URLConnection connection = url.openConnection(); | ||
InputStream in = connection.getInputStream(); | ||
|
||
byte[] buf = new byte[4096]; | ||
int read = 0; | ||
|
||
while((read = in.read(buf)) > 0) | ||
out.write(buf, 0, read); | ||
|
||
out.close(); | ||
in.close(); | ||
|
||
float secs = (float) (System.currentTimeMillis() - time) / 1000F; | ||
System.out.printf("Finished downloading %s (Took %.2fs)%n", name, secs); | ||
} catch(Exception e) { | ||
System.out.println("Failed to download " + name); | ||
e.printStackTrace(); | ||
} | ||
}; | ||
|
||
downloadCount++; | ||
executor.submit(run); | ||
} | ||
|
||
private void deleteRemovedMods() { | ||
System.out.println("Deleting any removed mods"); | ||
File[] files = modsDir.listFiles(f -> !f.isDirectory() && !acceptableFilenames.contains(f.getName())); | ||
|
||
if(files.length == 0) | ||
System.out.println("No mods were removed, woo!"); | ||
else { | ||
for(File f : files) { | ||
System.out.println("Found removed mod " + f.getName()); | ||
f.delete(); | ||
} | ||
|
||
System.out.println("Deleted " + files.length + " old mods"); | ||
} | ||
} | ||
|
||
private boolean modExists(File file) { | ||
if(file.exists()) | ||
return true; | ||
|
||
String name = file.getName(); | ||
|
||
if(name.endsWith(".disabled")) | ||
return swapIfExists(file, name.replaceAll("\\.disabled", "")); | ||
else return swapIfExists(file, name + ".disabled"); | ||
} | ||
|
||
private boolean swapIfExists(File target, String searchName) { | ||
File search = new File(modsDir, searchName); | ||
if(search.exists()) { | ||
System.out.println("Found alt file for " + target.getName() + " -> " + searchName + ", switching filename"); | ||
search.renameTo(target); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package vazkii.instancesync; | ||
|
||
public class Instance { | ||
|
||
public Addon[] installedAddons; | ||
|
||
public static class Addon { | ||
|
||
public AddonFile installedFile; | ||
|
||
@Override | ||
public String toString() { | ||
return installedFile == null ? "NO FILE" : installedFile.toString(); | ||
} | ||
|
||
public static class AddonFile { | ||
|
||
public String fileNameOnDisk; | ||
public String downloadUrl; | ||
|
||
@Override | ||
public String toString() { | ||
return fileNameOnDisk; | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package vazkii.instancesync; | ||
|
||
import java.io.File; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
|
||
import com.google.gson.Gson; | ||
|
||
public final class InstanceSync { | ||
|
||
public static void main(String[] args) { | ||
long time = System.currentTimeMillis(); | ||
File dir = new File("."); | ||
System.out.println("Running in " + dir.getAbsolutePath()); | ||
|
||
File instanceFile = new File(dir, "minecraftinstance.json"); | ||
if(!instanceFile.exists()) { | ||
System.out.println("No minecraftinstance.json file exists in this directory, aborting"); | ||
System.exit(1); | ||
} | ||
|
||
System.out.println("Found minecraftinstance.json file"); | ||
|
||
File mods = new File(dir, "mods"); | ||
if(mods.exists() && !mods.isDirectory()) { | ||
System.out.println("/mods exists but is a file, aborting"); | ||
System.exit(1); | ||
} | ||
|
||
if(!mods.exists()) { | ||
System.out.println("/mods does not exist, creating"); | ||
mods.mkdir(); | ||
} | ||
|
||
Gson gson = new Gson(); | ||
try { | ||
System.out.println("Reading minecraftinstance.json"); | ||
Instance instance = gson.fromJson(new FileReader(instanceFile), Instance.class); | ||
|
||
if(instance == null) { | ||
System.out.println("Couldn't load minecraftinstance.json, aborting"); | ||
System.exit(1); | ||
} | ||
|
||
System.out.println("Instance loaded, has " + instance.installedAddons.length + " mods\n"); | ||
|
||
DownloadManager manager = new DownloadManager(mods); | ||
manager.downloadInstance(instance); | ||
|
||
float secs = (float) (System.currentTimeMillis() - time) / 1000F; | ||
System.out.printf("%nDone! Took %.2fs%n", secs); | ||
} catch (IOException e) { | ||
System.out.println("ERROR: Something bad happened!"); | ||
e.printStackTrace(); | ||
} | ||
|
||
} | ||
|
||
} |