Skip to content

Commit

Permalink
1.2.9: PLA Update
Browse files Browse the repository at this point in the history
Fixed NPE on file deleter on empty mods folder

Added a ThreadPool for assets downloads
  • Loading branch information
FlowArg committed Nov 22, 2020
1 parent 366fe13 commit 1c4f337
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void onStart() {
*/
public Optifine getOptifine(String optifineVersion, boolean preview) throws IOException
{
final String name = preview ? optifineVersion + ".jar" : "OptiFine_" + optifineVersion + ".jar";
final String name = preview ? (optifineVersion.contains("preview_") && optifineVersion.contains("OptiFine_") ? optifineVersion + ".jar" : "preview_OptiFine_" + optifineVersion + ".jar") : "OptiFine_" + optifineVersion + ".jar";
final HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse("http://optifine.net/downloadx")).newBuilder();
urlBuilder.addQueryParameter("f", name);
urlBuilder.addQueryParameter("x", preview ? this.getJsonPreview(optifineVersion) : this.getJson(optifineVersion));
Expand All @@ -58,7 +58,6 @@ public Optifine getOptifine(String optifineVersion, boolean preview) throws IOEx
return new Optifine(name, length);
}


public void shutdownOKHTTP()
{
client.dispatcher().executorService().shutdown();
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ allprojects {
dependencies {
api 'com.google.code.gson:gson:2.8.6'
api 'fr.flowarg:flowmultitools:1.2.0'
implementation 'com.github.FlowArg:PluginLoaderAPI:871c5910c6'
implementation 'com.github.FlowArg:PluginLoaderAPI:6d674b6'
}
}

version '1.2.8'
version '1.2.9'
archivesBaseName = "flowupdater"

artifacts {
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/fr/flowarg/flowupdater/FlowUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class FlowUpdater
/** Represent a list of Runnable. Post Executions are called after update. */
private final List<Runnable> postExecutions;

/** The plugin manager object */
private final PluginManager pluginManager;

/** Default callback */
Expand Down Expand Up @@ -94,7 +95,7 @@ private FlowUpdater(VanillaVersion version, ILogger logger, UpdaterOptions updat
{
this.logger = logger;
this.version = version;
this.logger.info(String.format("------------------------- FlowUpdater for Minecraft %s v%s -------------------------", this.version.getName(), "1.2.8"));
this.logger.info(String.format("------------------------- FlowUpdater for Minecraft %s v%s -------------------------", this.version.getName(), "1.2.9"));
this.externalFiles = externalFiles;
this.postExecutions = postExecutions;
this.forgeVersion = forgeVersion;
Expand Down Expand Up @@ -172,13 +173,15 @@ private void updateMinecraft(File dir) throws Exception
this.downloadInfos.getMods().add(mod);
}

this.pluginManager.loadCurseForgePlugin(modsDir, this.forgeVersion);
this.pluginManager.loadOptifinePlugin(modsDir, this.forgeVersion);
if(this.updaterOptions.isEnableModsFromCurseForge())
this.pluginManager.loadCurseForgePlugin(modsDir, this.forgeVersion);
if(this.updaterOptions.isInstallOptifineAsMod())
this.pluginManager.loadOptifinePlugin(modsDir, this.forgeVersion);
}

if (!dir.exists())
dir.mkdirs();
final VanillaDownloader vanillaDownloader = new VanillaDownloader(dir, this.logger, this.callback, this.downloadInfos, this.updaterOptions.isReExtractNatives());
final VanillaDownloader vanillaDownloader = new VanillaDownloader(dir, this.logger, this.callback, this.downloadInfos, this.updaterOptions);
vanillaDownloader.download();

if (this.forgeVersion != null)
Expand Down
25 changes: 14 additions & 11 deletions src/main/java/fr/flowarg/flowupdater/download/DownloadInfos.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Represent information about download status. Used with {@link IProgressCallback} progress system.
Expand All @@ -16,41 +19,41 @@
public class DownloadInfos
{
private final List<Downloadable> libraryDownloadables = new ArrayList<>();
private final List<AssetDownloadable> assetDownloadables = new ArrayList<>();
private final Queue<AssetDownloadable> assetDownloadables = new ConcurrentLinkedDeque<>();
private final List<ExternalFile> extFiles = new ArrayList<>();
private final List<Mod> mods = new ArrayList<>();
private final List<Object> curseMods = new ArrayList<>();
private Object optifine = null;
private int totalToDownload;
private int downloaded;
private final AtomicInteger totalToDownload = new AtomicInteger();
private final AtomicInteger downloaded = new AtomicInteger();
private boolean init = false;

public void init()
{
if(!this.isInit())
{
this.totalToDownload = this.libraryDownloadables.size() + this.assetDownloadables.size() + this.extFiles.size() + this.mods.size() + this.curseMods.size() + (this.optifine == null ? 0 : 1);
this.downloaded = 0;
this.totalToDownload.set(this.libraryDownloadables.size() + this.assetDownloadables.size() + this.extFiles.size() + this.mods.size() + this.curseMods.size() + (this.optifine == null ? 0 : 1));
this.downloaded.set(0);
this.init = true;
}
}

public void incrementDownloaded()
{
++this.downloaded;
this.downloaded.incrementAndGet();
}

public int getTotalToDownload()
{
return this.totalToDownload;
return this.totalToDownload.get();
}

public int getDownloaded()
{
return this.downloaded;
return this.downloaded.get();
}

public List<AssetDownloadable> getAssetDownloadables()
public Queue<AssetDownloadable> getAssetDownloadables()
{
return this.assetDownloadables;
}
Expand Down Expand Up @@ -98,7 +101,7 @@ public void clear()
this.mods.clear();
this.curseMods.clear();
this.optifine = null;
this.totalToDownload = 0;
this.downloaded = 0;
this.totalToDownload.set(0);
this.downloaded.set(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
import fr.flowarg.flowupdater.download.json.AssetDownloadable;
import fr.flowarg.flowupdater.download.json.Downloadable;
import fr.flowarg.flowupdater.utils.IOUtils;
import fr.flowarg.flowupdater.utils.UpdaterOptions;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static fr.flowarg.flowio.FileUtils.*;

Expand All @@ -19,17 +23,19 @@ public class VanillaDownloader
private final IProgressCallback callback;
private final DownloadInfos downloadInfos;
private final boolean reExtractNatives;
private final int threadsForAssets;

private final File natives;
private final File assets;

public VanillaDownloader(File dir, ILogger logger, IProgressCallback callback, DownloadInfos infos, boolean reExtractNatives)
public VanillaDownloader(File dir, ILogger logger, IProgressCallback callback, DownloadInfos infos, UpdaterOptions options)
{
this.dir = dir;
this.logger = logger;
this.callback = callback;
this.downloadInfos = infos;
this.reExtractNatives = reExtractNatives;
this.reExtractNatives = options.isReExtractNatives();
this.threadsForAssets = options.getNmbrThreadsForAssets();

this.natives = new File(this.dir, "natives/");
this.assets = new File(this.dir, "assets/");
Expand Down Expand Up @@ -100,26 +106,38 @@ private void extractNatives() throws IOException
}

for (File toDelete : this.natives.listFiles())
{
if (toDelete.getName().endsWith(".git") || toDelete.getName().endsWith(".sha1")) toDelete.delete();
}
}
}

private void downloadAssets()
{
this.logger.info("Checking assets...");
this.callback.step(Step.DL_ASSETS);

for (AssetDownloadable assetDownloadable : this.downloadInfos.getAssetDownloadables())
final ThreadPoolExecutor threadPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(this.threadsForAssets);
for (int i = 0; i < threadPool.getMaximumPoolSize(); i++)
{
final File download = new File(this.assets, assetDownloadable.getFile());
threadPool.submit(() -> {
AssetDownloadable assetDownloadable;
while ((assetDownloadable = this.downloadInfos.getAssetDownloadables().poll()) != null)
{
final File download = new File(this.assets, assetDownloadable.getFile());

if (!download.exists() || getFileSizeBytes(download) != assetDownloadable.getSize())
IOUtils.download(this.logger, assetDownloadable.getUrl(), download);
if (!download.exists() || getFileSizeBytes(download) != assetDownloadable.getSize())
IOUtils.download(this.logger, assetDownloadable.getUrl(), download);

this.downloadInfos.incrementDownloaded();
this.callback.update(this.downloadInfos.getDownloaded(), this.downloadInfos.getTotalToDownload());
this.downloadInfos.incrementDownloaded();
this.callback.update(this.downloadInfos.getDownloaded(), this.downloadInfos.getTotalToDownload());
}
});
}
try
{
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e)
{
this.logger.printStackTrace(e);
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/fr/flowarg/flowupdater/utils/IFileDeleter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package fr.flowarg.flowupdater.utils;

@FunctionalInterface
public interface IFileDeleter
{
/**
* Delete all bad files in the provided directory.
* @param parameters all parameters required by the FileDeleter implementation
* @throws Exception throwed if an error occurred
*/
void delete(Object... parameters) throws Exception;
}
95 changes: 49 additions & 46 deletions src/main/java/fr/flowarg/flowupdater/utils/ModFileDeleter.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,49 +38,70 @@ public void delete(Object... parameters) throws Exception
final Set<File> badFiles = new HashSet<>();
final List<File> verifiedFiles = new ArrayList<>();
Arrays.stream(this.modsToIgnore).forEach(fileName -> verifiedFiles.add(new File(modsDir, fileName)));
for(File fileInDir : modsDir.listFiles())
if(modsDir.listFiles().length != 0)
{
if(!fileInDir.isDirectory())
for(File fileInDir : modsDir.listFiles())
{
if(verifiedFiles.contains(fileInDir))
continue;
if(mods.isEmpty() && allCurseMods.isEmpty() && optifineParam == null)
if(!fileInDir.isDirectory())
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
}
else
{
if(cursePluginLoaded)
if(verifiedFiles.contains(fileInDir))
continue;
if(mods.isEmpty() && allCurseMods.isEmpty() && optifineParam == null)
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
}
else
{
for(Object obj : allCurseMods)
if(cursePluginLoaded)
{
final CurseMod mod = (CurseMod)obj;
if(mod.getName().equalsIgnoreCase(fileInDir.getName()))
for(Object obj : allCurseMods)
{
if(getMD5ofFile(fileInDir).equalsIgnoreCase(mod.getMd5()) && getFileSizeBytes(fileInDir) == mod.getLength())
final CurseMod mod = (CurseMod)obj;
if(mod.getName().equalsIgnoreCase(fileInDir.getName()))
{
badFiles.remove(fileInDir);
verifiedFiles.add(fileInDir);
if(getMD5ofFile(fileInDir).equalsIgnoreCase(mod.getMd5()) && getFileSizeBytes(fileInDir) == mod.getLength())
{
badFiles.remove(fileInDir);
verifiedFiles.add(fileInDir);
}
else badFiles.add(fileInDir);
}
else
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
}
else badFiles.add(fileInDir);
}
else
}

if(optifinePluginLoaded)
{
final Optifine optifine = (Optifine)optifineParam;
if(optifine != null)
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
if(optifine.getName().equalsIgnoreCase(fileInDir.getName()))
{
if(getFileSizeBytes(fileInDir) == optifine.getSize())
{
badFiles.remove(fileInDir);
verifiedFiles.add(fileInDir);
}
else badFiles.add(fileInDir);
}
else
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
}
}
}
}

if(optifinePluginLoaded)
{
final Optifine optifine = (Optifine)optifineParam;
if(optifine != null)
for(Mod mod : mods)
{
if(optifine.getName().equalsIgnoreCase(fileInDir.getName()))
if(mod.getName().equalsIgnoreCase(fileInDir.getName()))
{
if(getFileSizeBytes(fileInDir) == optifine.getSize())
if(getSHA1(fileInDir).equalsIgnoreCase(mod.getSha1()) && getFileSizeBytes(fileInDir) == mod.getSize())
{
badFiles.remove(fileInDir);
verifiedFiles.add(fileInDir);
Expand All @@ -94,24 +115,6 @@ public void delete(Object... parameters) throws Exception
}
}
}

for(Mod mod : mods)
{
if(mod.getName().equalsIgnoreCase(fileInDir.getName()))
{
if(getSHA1(fileInDir).equalsIgnoreCase(mod.getSha1()) && getFileSizeBytes(fileInDir) == mod.getSize())
{
badFiles.remove(fileInDir);
verifiedFiles.add(fileInDir);
}
else badFiles.add(fileInDir);
}
else
{
if(!verifiedFiles.contains(fileInDir))
badFiles.add(fileInDir);
}
}
}
}
}
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/fr/flowarg/flowupdater/utils/PluginManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,20 +158,20 @@ public void loadOptifinePlugin(File dir, AbstractForgeVersion forgeVersion)
{
Class.forName("fr.antoineok.flowupdater.optifineplugin.OptifinePlugin");
this.optifinePluginLoaded = true;
try
{
final OptifinePlugin optifinePlugin = OptifinePlugin.instance;
final Optifine optifine = optifinePlugin.getOptifine(forgeVersion.getOptifine().getVersion(), forgeVersion.getOptifine().isPreview());
this.downloadInfos.setOptifine(optifine);
} catch (Exception e)
{
this.logger.printStackTrace(e);
}
} catch (ClassNotFoundException e)
{
this.optifinePluginLoaded = false;
this.logger.err("Cannot install optifine: OptifinePlugin is not loaded. Please, enable the 'installOptifineAsMod' updater option !");
}
try
{
final OptifinePlugin optifinePlugin = OptifinePlugin.instance;
final Optifine optifine = optifinePlugin.getOptifine(forgeVersion.getOptifine().getVersion(), forgeVersion.getOptifine().isPreview());
this.downloadInfos.setOptifine(optifine);
} catch (Exception e)
{
this.logger.printStackTrace(e);
}
}

public void configurePLA(File dir)
Expand All @@ -180,6 +180,7 @@ public void configurePLA(File dir)
PluginLoaderAPI.registerPluginLoader(new PluginLoader("FlowUpdater", new File(dir, "FUPlugins/"), PluginManager.class)).complete();
PluginLoaderAPI.removeDefaultShutdownTrigger().complete();
PluginLoaderAPI.ready(PluginManager.class).complete();
while (!PluginLoaderAPI.finishedLoading()) ;
}

public void shutdown()
Expand Down
Loading

0 comments on commit 1c4f337

Please sign in to comment.