Skip to content

Commit

Permalink
Merge pull request #213 from 3arthqu4ke/progressbar
Browse files Browse the repository at this point in the history
Added progress bar for downloads
  • Loading branch information
3arthqu4ke authored Nov 13, 2024
2 parents 37cb912 + 04e4394 commit 17cbdc7
Show file tree
Hide file tree
Showing 15 changed files with 265 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ public void setHidingPasswordsSupported(boolean hidingPasswordsSupported) {
passwordContext.setHidingPasswordsSupported(hidingPasswordsSupported);
}

@Override
public Progressbar displayProgressBar(Progressbar.Configuration configuration) {
CommandLineReader commandLineReader = this.commandLineReader;
if (commandLineReader != null) {
return commandLineReader.displayProgressBar(configuration);
}

return Progressbar.dummy();
}

private static final class EmptyCommandContext implements CommandContext {
private static final EmptyCommandContext INSTANCE = new EmptyCommandContext();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,11 @@ default void close() throws IOException {
// see JLineCommandLineReader
}

/**
* @return a Progressbar to display progress with.
*/
default Progressbar displayProgressBar(Progressbar.Configuration configuration) {
return Progressbar.dummy();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package me.earth.headlessmc.api.command.line;

import lombok.Data;

public interface Progressbar extends AutoCloseable {
void stepBy(long n);

void stepTo(long n);

void step();

void maxHint(long n);

boolean isDummy();

@Override
void close();

static Progressbar dummy() {
return new Progressbar() {
@Override
public void close() {

}

@Override
public void stepBy(long n) {

}

@Override
public void stepTo(long n) {

}

@Override
public void step() {

}

@Override
public void maxHint(long n) {

}

@Override
public boolean isDummy() {
return true;
}
};
}

@Data
class Configuration {
private final String taskName;
private final long initialMax;
}

}
3 changes: 3 additions & 0 deletions headlessmc-jline/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
dependencies {
api project(':headlessmc-api')
api 'org.jline:jline:3.26.3'
api ('me.tongfei:progressbar:0.9.5') {
exclude module: 'jline'
}
implementation 'net.java.dev.jna:jna:5.14.0'
// TODO: maybe also package jansi for testing?
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.command.line.CommandLine;
import me.earth.headlessmc.api.command.line.CommandLineReader;
import me.earth.headlessmc.api.command.line.Progressbar;
import me.earth.headlessmc.api.config.Property;
import me.earth.headlessmc.api.process.InAndOutProvider;
import me.tongfei.progressbar.ProgressBarBuilder;
import me.tongfei.progressbar.ProgressBarStyle;
import org.jetbrains.annotations.Nullable;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
Expand Down Expand Up @@ -48,6 +51,9 @@ public class JLineCommandLineReader implements CommandLineReader {
*/
protected volatile boolean dumb;

protected volatile boolean enableProgressbar = Boolean.parseBoolean(System.getProperty(JLineProperties.ENABLE_PROGRESS_BAR.getName(), "true"));
protected volatile String progressBarStyle = System.getProperty(JLineProperties.PROGRESS_BAR_STYLE.getName());

@Override
public void read(HeadlessMc hmc) throws IOError {
CommandLine commandLine = hmc.getCommandLine();
Expand Down Expand Up @@ -99,6 +105,8 @@ public void read(HeadlessMc hmc) throws IOError {

@Override
public synchronized void open(HeadlessMc hmc) throws IOException {
enableProgressbar = hmc.getConfig().get(JLineProperties.ENABLE_PROGRESS_BAR, true);
progressBarStyle = hmc.getConfig().get(JLineProperties.PROGRESS_BAR_STYLE, null);
if (hmc.getConfig().get(JLineProperties.PREVENT_DEPRECATION_WARNING, true)) {
System.setProperty("org.jline.terminal.disableDeprecatedProviderWarning", "true");
}
Expand Down Expand Up @@ -140,6 +148,39 @@ public synchronized void close() throws IOException {
}
}

@Override
public Progressbar displayProgressBar(Progressbar.Configuration configuration) {
Terminal currentTerminal = terminal;
if (currentTerminal == null || !enableProgressbar) {
return Progressbar.dummy();
}

ProgressBarBuilder builder = new ProgressBarBuilder();
builder.setTaskName(configuration.getTaskName());
builder.setInitialMax(configuration.getInitialMax());
String style = progressBarStyle;
if (style != null) {
// ProgressBarStyle is not an enum anymore after 0.10.0
switch (style) {
case "COLORFUL_UNICODE_BLOCK":
builder.setStyle(ProgressBarStyle.COLORFUL_UNICODE_BLOCK);
break;
case "COLORFUL_UNICODE_BAR":
builder.setStyle(ProgressBarStyle.COLORFUL_UNICODE_BAR);
break;
case "UNICODE_BLOCK":
builder.setStyle(ProgressBarStyle.UNICODE_BLOCK);
break;
case "ASCII":
builder.setStyle(ProgressBarStyle.ASCII);
break;
default:
}
}

return new JlineProgressbar(builder.build());
}

protected Terminal buildTerminal(HeadlessMc hmc, boolean dumb, String providers, InAndOutProvider io) throws IOException {
return buildTerminalBuilder(hmc, dumb, providers, io).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ public interface JLineProperties {
Property<Boolean> EXEC = PropertyTypes.bool("hmc.jline.exec");
Property<Boolean> SYSTEM = PropertyTypes.bool("hmc.jline.system");

Property<Boolean> ENABLE_PROGRESS_BAR = PropertyTypes.bool("hmc.jline.enable.progressbar");
Property<String> PROGRESS_BAR_STYLE = PropertyTypes.string("hmc.jline.progressbar.style");

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package me.earth.headlessmc.jline;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.earth.headlessmc.api.command.line.Progressbar;
import me.tongfei.progressbar.ProgressBar;

@Getter
@RequiredArgsConstructor
public class JlineProgressbar implements Progressbar {
private final ProgressBar progressBar;

@Override
public void stepBy(long n) {
progressBar.stepBy(n);
}

@Override
public void stepTo(long n) {
progressBar.stepTo(n);
}

@Override
public void step() {
progressBar.step();
}

@Override
public void maxHint(long n) {
progressBar.maxHint(n);
}

@Override
public void close() {
progressBar.close();
}

@Override
public boolean isDummy() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void execute(Version version, String... args) throws CommandException {
private void checkAssets(Version version, int[] values, String...args) throws IOException {
if (CommandUtil.hasFlag("-assets", args)) {
ctx.log("Checking assets of version " + version.getName());
AssetsDownloader assetsDownloader = new AssetsDownloader(ctx.getDownloadService(), ctx, ctx.getMcFiles(), version.getAssetsUrl(), version.getAssets()) {
AssetsDownloader assetsDownloader = new AssetsDownloader(ctx.getCommandLine(), ctx.getDownloadService(), ctx, ctx.getMcFiles(), version.getAssetsUrl(), version.getAssets()) {
@Override
protected void downloadAsset(String progress, String name, String hash, @Nullable Long size, boolean mapToResources) throws IOException {
val firstTwo = hash.substring(0, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ public void execute(Version version, String... args) throws CommandException {
boolean quit = flag(ctx, "-quit", LauncherProperties.INVERT_QUIT_FLAG, LauncherProperties.ALWAYS_QUIT_FLAG, args);
int status = 0;
try {
if (!prepare) {
ctx.getCommandLine().close();
}

status = runProcess(version, files, quit, prepare, args);
} catch (IOException | LaunchException | AuthException e) {
} catch (LaunchException | AuthException e) {
status = -1;
log.error(e);
ctx.log(String.format("Couldn't launch %s: %s", version.getName(), e.getMessage()));
Expand Down Expand Up @@ -112,6 +108,7 @@ private int runProcess(Version version, FileManager files, boolean quit, boolean
.version(version)
.launcher(ctx)
.files(files)
.closeCommandLine(!prepare)
.parseFlags(ctx, quit, args)
.prepare(prepare)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import com.google.gson.JsonObject;
import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.val;
import me.earth.headlessmc.api.command.line.CommandLine;
import me.earth.headlessmc.api.command.line.Progressbar;
import me.earth.headlessmc.api.config.HasConfig;
import me.earth.headlessmc.launcher.LauncherProperties;
import me.earth.headlessmc.launcher.files.FileManager;
Expand All @@ -25,12 +28,16 @@ public class AssetsDownloader {
private final ChecksumService checksumService = new ChecksumService();
private final DummyAssets dummyAssets = new DummyAssets();

private final CommandLine commandLine;
private final DownloadService downloadService;
private final HasConfig config;
private final FileManager files;
private final String url;
private final String id;

@Setter
protected boolean shouldLog = true;

public void download() throws IOException {
Path index = files.getDir("assets").toPath().resolve("indexes").resolve(id + ".json");
// Why does this file always corrupt on CheerpJ?
Expand All @@ -51,18 +58,26 @@ public void download() throws IOException {
config.getConfig().get(LauncherProperties.ASSETS_BACKOFF, true)
);

objects.getAsJsonObject().entrySet().forEach(entry -> ioService.addTask(progress -> {
JsonObject jo = entry.getValue().getAsJsonObject();
downloadAsset(
progress,
entry.getKey(),
jo.get("hash").getAsString(),
jo.get("size") == null ? null : jo.get("size").getAsLong(),
jo.get("map_to_resources") != null && jo.get("map_to_resources").getAsBoolean()
);
}));

ioService.execute();
// TODO: provide better ETA, later assets take longer
try (Progressbar progressbar = commandLine.displayProgressBar(new Progressbar.Configuration("Downloading Assets", objects.size()))) {
ioService.setShouldLog(progressbar.isDummy());
shouldLog = progressbar.isDummy();

objects.getAsJsonObject().entrySet().forEach(entry -> ioService.addTask(progress -> {
JsonObject jo = entry.getValue().getAsJsonObject();
downloadAsset(
progress,
entry.getKey(),
jo.get("hash").getAsString(),
jo.get("size") == null ? null : jo.get("size").getAsLong(),
jo.get("map_to_resources") != null && jo.get("map_to_resources").getAsBoolean()
);

progressbar.step();
}));

ioService.execute();
}
}

protected void downloadAsset(String progress, String name, String hash, @Nullable Long size, boolean mapToResources) throws IOException {
Expand Down Expand Up @@ -94,7 +109,10 @@ protected void downloadAsset(String progress, String name, String hash, @Nullabl

protected byte @Nullable [] download(String firstTwo, String hash, String progress, String name, Path to, @Nullable Long size) throws IOException {
val from = URL + firstTwo + "/" + hash;
log.info(progress + " Downloading: " + name + " from " + from + " to " + to);
if (shouldLog) {
log.info(progress + " Downloading: " + name + " from " + from + " to " + to);
}

boolean checkHash = config.getConfig().get(LauncherProperties.ASSETS_CHECK_HASH, true);
boolean checkSize = checkHash || config.getConfig().get(LauncherProperties.ASSETS_CHECK_SIZE, true);
Long expectedSize = checkSize ? size : null;
Expand All @@ -115,7 +133,12 @@ protected void copyToLegacy(String name, Path file, String hash, @Nullable Long
if ("pre-1.6".equals(id)) {
// TODO: old versions have the map_to_resource thing, copy to resources
val legacy = files.getDir("assets").toPath().resolve("virtual").resolve("legacy").resolve(name);
log.info("Legacy version, copying to " + legacy);
if (shouldLog) {
log.info("Legacy version, copying to " + legacy);
} else {
log.debug("Legacy version, copying to " + legacy);
}

integrityCheck("Legacy", legacy, hash, size);
if (copy && !Files.exists(legacy)) {
Files.copy(file, legacy, StandardCopyOption.REPLACE_EXISTING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import me.earth.headlessmc.api.config.HasConfig;
import me.earth.headlessmc.launcher.LauncherProperties;
import me.earth.headlessmc.launcher.os.OS;
Expand All @@ -18,10 +19,16 @@ public class LibraryDownloader {
private final HasConfig config;
private final OS os;

@Setter
private boolean shouldLog = true;

public void download(Library library, Path to) throws IOException {
String libPath = library.getPath(os);
String url = library.getUrl(libPath);
log.info(libPath + " is missing, downloading from " + url);
if (shouldLog) {
log.info(libPath + " is missing, downloading from " + url);
}

download(url, to, library.getSha1(), library.getSize());
}

Expand Down
Loading

0 comments on commit 17cbdc7

Please sign in to comment.