Skip to content

Commit

Permalink
feat(obfuscator): began works on custom renderer for progress bar + h…
Browse files Browse the repository at this point in the history
…ard dependency requirement
  • Loading branch information
terminalsin committed Jun 13, 2022
1 parent af42a90 commit 33581a4
Show file tree
Hide file tree
Showing 8 changed files with 546 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// so a dfs goes through edges towards the root
public class ClassTree extends FastDirectedGraph<ClassNode, InheritanceEdge> {
private static final Logger LOGGER = Logger.getLogger(ClassTree.class);
private static final boolean ALLOW_PHANTOM_CLASSES = true;
private static final boolean ALLOW_PHANTOM_CLASSES = false;

private final ApplicationClassSource source;
private final ClassNode rootNode;
Expand All @@ -45,6 +45,12 @@ protected void init() {
addVertex(node);
}
}

public void verify() {
for (ClassNode node : source.iterateWithLibraries()) {
verifyVertex(node);
}
}

public ClassNode getRootNode() {
return rootNode;
Expand Down Expand Up @@ -166,6 +172,32 @@ private ClassNode requestClass0(String name, String from) {
throw new RuntimeException("request from " + from, e);
}
}

public void verifyVertex(ClassNode cn) {
if(cn == null) {
throw new IllegalStateException("Vertex is null!");
}

if (!containsVertex(cn)) {
addVertex(cn);
}

if(cn != rootNode) {
ClassNode sup = cn.node.superName != null
? requestClass0(cn.node.superName, cn.getName())
: rootNode;
if(sup == null) {
throw new IllegalStateException(String.format("No superclass %s for %s", cn.node.superName, cn.getName()));
}

for (String s : cn.node.interfaces) {
ClassNode iface = requestClass0(s, cn.getName());
if(iface == null) {
throw new IllegalStateException(String.format("No superinterface %s for %s", s, cn.getName()));
}
}
}
}

@Override
public boolean addVertex(ClassNode cn) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,27 @@ public void run() {
}
LOGGER.log("Finished importing the JVM!");

/* Checking for errors */
LOGGER.post("Starting verification");
try {
classSource.getClassTree().verify();
} catch (Exception e) {
System.out.println(
"-----------------------------------------------------\n"
+ "/!\\ Skidfuscator failed to compute some libraries!\n"
+ "It it advised to read https://github.com/terminalsin/skidfuscator-java-obfuscator/wiki/Libraries\n"
+ "\n"
+ "Error: " + e.getMessage() + "\n" +
(e.getCause() == null
? "\n"
: " " + e.getCause().getMessage() + "\n"
)
+ "-----------------------------------------------------\n"
);
System.exit(1);
return;
}

/* Resolve context */
LOGGER.post("Resolving basic context...");
this.cxt = new BasicAnalysisContext.BasicContextBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package dev.skidfuscator.obfuscator.util.progress;

import me.tongfei.progressbar.ProgressBarRenderer;
import me.tongfei.progressbar.ProgressBarStyle;

import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

import static dev.skidfuscator.obfuscator.util.progress.StringDisplayUtils.getStringDisplayLength;
import static dev.skidfuscator.obfuscator.util.progress.StringDisplayUtils.trimDisplayLength;

/**
* Default progress bar renderer (see {@link ProgressBarRenderer}).
* @author Tongfei Chen
* @author Muhammet Sakarya
* @since 0.8.0
*/
public class SkidProgressBarRenderer {

private ProgressBarStyle style;
private String unitName;
private long unitSize;
private boolean isSpeedShown;
private DecimalFormat speedFormat;
private ChronoUnit speedUnit;
private Spinner<String> values = new Spinner<>(
"⠋",
"⠙",
"⠹",
"⠸",
"⠼",
"⠴",
"⠦",
"⠧",
"⠇",
"⠏"
);

protected SkidProgressBarRenderer(
ProgressBarStyle style,
String unitName,
long unitSize,
boolean isSpeedShown,
DecimalFormat speedFormat,
ChronoUnit speedUnit
) {
this.style = style;
this.unitName = unitName;
this.unitSize = unitSize;
this.isSpeedShown = isSpeedShown;
this.speedFormat = isSpeedShown && speedFormat == null ? new DecimalFormat() : speedFormat;
this.speedUnit = speedUnit;
}

// Number of full blocks
protected int progressIntegralPart(SkidProgressState progress, int length) {
return (int)(progress.getNormalizedProgress() * length);
}

protected int progressFractionalPart(SkidProgressState progress, int length) {
double p = progress.getNormalizedProgress() * length;
double fraction = (p - Math.floor(p)) ;//* style.fractionSymbols.length();
return (int) Math.floor(fraction);
}

protected String eta(SkidProgressState progress, Duration elapsed) {
if (progress.max <= 0 || progress.indefinite) return "?";
else if (progress.current - progress.start == 0) return "?";
else return Util.formatDuration(
elapsed.dividedBy(progress.current - progress.start).multipliedBy(progress.max - progress.current)
);
}

protected String percentage(SkidProgressState progress) {
String res;
if (progress.max <= 0 || progress.indefinite) res = "? %";
else res = String.valueOf((int) Math.floor(100.0 * progress.current / progress.max)) + "%";
return Util.repeat(' ', 4 - res.length()) + res;
}

protected String ratio(SkidProgressState progress) {
String m = progress.indefinite ? "?" : String.valueOf(progress.max / unitSize);
String c = String.valueOf(progress.current / unitSize);
return Util.repeat(' ', m.length() - c.length()) + c + "/" + m + unitName;
}

protected String speed(SkidProgressState progress, Duration elapsed) {
String suffix = "/s";
double elapsedSeconds = elapsed.getSeconds();
double elapsedInUnit = elapsedSeconds;
if (null != speedUnit)
switch (speedUnit) {
case MINUTES:
suffix = "/min";
elapsedInUnit /= 60;
break;
case HOURS:
suffix = "/h";
elapsedInUnit /= (60 * 60);
break;
case DAYS:
suffix = "/d";
elapsedInUnit /= (60 * 60 * 24);
break;
}

if (elapsedSeconds == 0)
return "?" + unitName + suffix;
double speed = (double) (progress.current - progress.start) / elapsedInUnit;
double speedWithUnit = speed / unitSize;
return speedFormat.format(speedWithUnit) + unitName + suffix;
}

public String render(SkidProgressState progress, int maxLength) {
if (maxLength <= 0) {
return "";
}
/*
Instant currTime = Instant.now();
Duration elapsed = Duration.between(progress.startInstant, currTime);
String prefix = progress.taskName + " (" + percentage(progress) + ") " + style.leftBracket;
int prefixLength = getStringDisplayLength(prefix);
if (prefixLength > maxLength) {
prefix = trimDisplayLength(prefix, maxLength - 1);
prefixLength = maxLength - 1;
}
// length of progress should be at least 1
int maxSuffixLength = Math.max(maxLength - prefixLength - 1, 0);
String speedString = isSpeedShown ? speed(progress, elapsed) : "";
String suffix = style.rightBracket + " " + ratio(progress) + " ("
+ Util.formatDuration(elapsed) + " / " + eta(progress, elapsed) + ") "
+ speedString + progress.extraMessage;
int suffixLength = getStringDisplayLength(suffix);
// trim excessive suffix
if (suffixLength > maxSuffixLength) {
suffix = trimDisplayLength(suffix, maxSuffixLength);
suffixLength = maxSuffixLength;
}
int length = maxLength - prefixLength - suffixLength;
StringBuilder sb = new StringBuilder(maxLength);
sb.append(prefix);
// case of indefinite progress bars
if (progress.indefinite) {
int pos = (int)(progress.current % length);
sb.append(Util.repeat(' ', pos));
sb.append(values.next());
sb.append(Util.repeat(' ', length - pos - 1));
}
// case of definite progress bars
else {
sb.append(Util.repeat(style.block, progressIntegralPart(progress, length)));
if (progress.current < progress.max) {
sb.append(style.fractionSymbols.charAt(progressFractionalPart(progress, length)));
sb.append(Util.repeat(style.space, length - progressIntegralPart(progress, length) - 1));
}
}
sb.append(suffix);*/
return null; //sb.toString();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package dev.skidfuscator.obfuscator.util.progress;

import java.time.Duration;
import java.time.Instant;

/**
* Encapsulates the internal states of a progress bar.
* @author Tongfei Chen
* @since 0.5.0
*/
class SkidProgressState {

String taskName;
String extraMessage = "";

boolean indefinite = false;

// 0 start current max
// [===============|=========> ]
long start;
long current;
long max;

Instant startInstant = null;
Duration elapsedBeforeStart = Duration.ZERO;

volatile boolean alive = true;
volatile boolean paused = false;

SkidProgressState(String taskName, long initialMax, long startFrom, Duration elapsedBeforeStart) {
this.taskName = taskName;
this.max = initialMax;
if (initialMax < 0) indefinite = true;
this.start = startFrom;
this.current = startFrom;
this.elapsedBeforeStart = elapsedBeforeStart;
this.startInstant = Instant.now();
}

String getTaskName() {
return taskName;
}

synchronized String getExtraMessage() {
return extraMessage;
}

synchronized long getCurrent() {
return current;
}

synchronized long getMax() {
return max;
}

// The progress, normalized to range [0, 1].
synchronized double getNormalizedProgress() {
if (max <= 0) return 0.0;
else if (current > max) return 1.0;
else return ((double)current) / max;
}

synchronized void setAsDefinite() {
indefinite = false;
}

synchronized void setAsIndefinite() {
indefinite = true;
}

synchronized void maxHint(long n) {
max = n;
}

synchronized void stepBy(long n) {
current += n;
if (current > max) max = current;
}

synchronized void stepTo(long n) {
current = n;
if (current > max) max = current;
}

synchronized void setExtraMessage(String msg) {
extraMessage = msg;
}

synchronized void pause() {
paused = true;
start = current;
elapsedBeforeStart = elapsedBeforeStart.plus(Duration.between(startInstant, Instant.now()));
}

synchronized void resume() {
paused = false;
startInstant = Instant.now();
}

synchronized void reset() {
start = 0;
current = 0;
startInstant = Instant.now();
elapsedBeforeStart = Duration.ZERO;
}

synchronized void kill() {
alive = false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.skidfuscator.obfuscator.util.progress;

/**
* @author Ghast
* @since 07/02/2021
* Artemis © 2021
*/
public class Spinner<T> {
private final T[] values;
private int index;

public Spinner(T... values) {
this.values = values;
this.index = 0;
}

public T next() {
return values[index = (++index % values.length)];
}
}
Loading

0 comments on commit 33581a4

Please sign in to comment.