This commit is contained in:
huanghongxun
2018-02-22 15:02:12 +08:00
parent 6c4231a6b2
commit 7a788d1e6e
24 changed files with 121 additions and 71 deletions

View File

@@ -21,6 +21,7 @@ import com.google.gson.JsonParseException;
import org.jackhuang.hmcl.mod.Modpack; import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.util.CompressingUtils; import org.jackhuang.hmcl.util.CompressingUtils;
import org.jackhuang.hmcl.util.JsonUtils; import org.jackhuang.hmcl.util.JsonUtils;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import java.io.File; import java.io.File;
@@ -33,7 +34,7 @@ import java.util.List;
*/ */
public final class HMCLModpackManager { public final class HMCLModpackManager {
public static final List<String> MODPACK_BLACK_LIST = Arrays.asList( public static final List<String> MODPACK_BLACK_LIST = Lang.immutableListOf(
"usernamecache.json", "usercache.json", // Minecraft "usernamecache.json", "usercache.json", // Minecraft
"launcher_profiles.json", "launcher.pack.lzma", // Minecraft Launcher "launcher_profiles.json", "launcher.pack.lzma", // Minecraft Launcher
"pack.json", "launcher.jar", "hmclmc.log", // HMCL "pack.json", "launcher.jar", "hmclmc.log", // HMCL
@@ -43,7 +44,7 @@ public final class HMCLModpackManager {
"downloads", // Curse "downloads", // Curse
"asm", "backups", "TCNodeTracker", "CustomDISkins", "data" // Mods "asm", "backups", "TCNodeTracker", "CustomDISkins", "data" // Mods
); );
public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Arrays.asList( public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Lang.immutableListOf(
"fonts", // BetterFonts "fonts", // BetterFonts
"saves", "servers.dat", "options.txt", // Minecraft "saves", "servers.dat", "options.txt", // Minecraft
"blueprints" /* BuildCraft */, "blueprints" /* BuildCraft */,

View File

@@ -221,10 +221,8 @@ public final class LauncherHelper {
} }
public static void stopManagedProcesses() { public static void stopManagedProcesses() {
synchronized (PROCESSES) { while (!PROCESSES.isEmpty())
while (!PROCESSES.isEmpty()) Optional.ofNullable(PROCESSES.poll()).ifPresent(ManagedProcess::stop);
Optional.ofNullable(PROCESSES.poll()).ifPresent(ManagedProcess::stop);
}
} }
public void emitStatus(LoadingState state) { public void emitStatus(LoadingState state) {

View File

@@ -28,7 +28,7 @@ import java.util.List;
public final class DownloadProviders { public final class DownloadProviders {
private DownloadProviders() {} private DownloadProviders() {}
public static List<DownloadProvider> DOWNLOAD_PROVIDERS = Arrays.asList(MojangDownloadProvider.INSTANCE, BMCLAPIDownloadProvider.INSTANCE); public static final List<DownloadProvider> DOWNLOAD_PROVIDERS = Lang.immutableListOf(MojangDownloadProvider.INSTANCE, BMCLAPIDownloadProvider.INSTANCE);
public static DownloadProvider getDownloadProvider(int index) { public static DownloadProvider getDownloadProvider(int index) {
return Lang.get(DOWNLOAD_PROVIDERS, index).orElse(MojangDownloadProvider.INSTANCE); return Lang.get(DOWNLOAD_PROVIDERS, index).orElse(MojangDownloadProvider.INSTANCE);

View File

@@ -54,7 +54,7 @@ public final class Locales {
*/ */
public static final SupportedLocale RU = new SupportedLocale(new Locale("ru")); public static final SupportedLocale RU = new SupportedLocale(new Locale("ru"));
public static final List<SupportedLocale> LOCALES = Arrays.asList(DEFAULT, EN, ZH_CN); public static final List<SupportedLocale> LOCALES = Lang.immutableListOf(DEFAULT, EN, ZH_CN);
public static SupportedLocale getLocale(int index) { public static SupportedLocale getLocale(int index) {
return Lang.get(LOCALES, index).orElse(DEFAULT); return Lang.get(LOCALES, index).orElse(DEFAULT);

View File

@@ -29,7 +29,7 @@ import java.util.List;
public final class Proxies { public final class Proxies {
private Proxies() {} private Proxies() {}
public static final List<Proxy.Type> PROXIES = Arrays.asList(Proxy.Type.DIRECT, Proxy.Type.HTTP, Proxy.Type.SOCKS); public static final List<Proxy.Type> PROXIES = Lang.immutableListOf(Proxy.Type.DIRECT, Proxy.Type.HTTP, Proxy.Type.SOCKS);
public static Proxy.Type getProxyType(int index) { public static Proxy.Type getProxyType(int index) {
return Lang.get(PROXIES, index).orElse(null); return Lang.get(PROXIES, index).orElse(null);

View File

@@ -42,10 +42,7 @@ import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle; import javafx.scene.shape.Rectangle;
import javafx.util.Duration; import javafx.util.Duration;
import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Main;
import org.jackhuang.hmcl.util.ExceptionalSupplier; import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.OperatingSystem;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -223,7 +220,11 @@ public final class FXUtils {
} }
public static void openFolder(File file) { public static void openFolder(File file) {
file.mkdirs(); if (!FileUtils.makeDirectory(file)) {
Logging.LOG.log(Level.SEVERE, "Unable to make directory " + file);
return;
}
String path = file.getAbsolutePath(); String path = file.getAbsolutePath();
switch (OperatingSystem.CURRENT_OS) { switch (OperatingSystem.CURRENT_OS) {

View File

@@ -138,6 +138,9 @@ public final class LogWindow extends Stage {
case DEBUG: case DEBUG:
debug.set(debug.get() + 1); debug.set(debug.get() + 1);
break; break;
default:
// ignore
break;
} }
} }

View File

@@ -216,6 +216,8 @@ public final class MainPage extends StackPane implements DecoratorPage {
case 3: case 3:
FXUtils.openFolder(profile.getRepository().getRunDirectory(rightClickedVersion)); FXUtils.openFolder(profile.getRepository().getRunDirectory(rightClickedVersion));
break; break;
default:
throw new Error();
} }
} }

View File

@@ -41,7 +41,6 @@ public class ComponentListCell extends StackPane {
private final Node content; private final Node content;
private Animation expandAnimation; private Animation expandAnimation;
private Rectangle clipRect; private Rectangle clipRect;
private double animatedHeight;
private final BooleanProperty expanded = new SimpleBooleanProperty(this, "expanded", false); private final BooleanProperty expanded = new SimpleBooleanProperty(this, "expanded", false);
public ComponentListCell(Node content) { public ComponentListCell(Node content) {
@@ -129,18 +128,13 @@ public class ComponentListCell extends StackPane {
updateClip(newHeight); updateClip(newHeight);
} }
animatedHeight = newAnimatedHeight;
expandAnimation = new Timeline(new KeyFrame(new Duration(320.0), expandAnimation = new Timeline(new KeyFrame(new Duration(320.0),
new KeyValue(container.minHeightProperty(), contentHeight, FXUtils.SINE), new KeyValue(container.minHeightProperty(), contentHeight, FXUtils.SINE),
new KeyValue(container.maxHeightProperty(), contentHeight, FXUtils.SINE) new KeyValue(container.maxHeightProperty(), contentHeight, FXUtils.SINE)
)); ));
if (!isExpanded()) { if (!isExpanded()) {
expandAnimation.setOnFinished(e2 -> { expandAnimation.setOnFinished(e2 -> updateClip(newHeight));
updateClip(newHeight);
animatedHeight = 0.0;
});
} }
expandAnimation.play(); expandAnimation.play();

View File

@@ -137,6 +137,8 @@ public final class MessageBox {
case OK_CANCEL_OPTION: case OK_CANCEL_OPTION:
alert.getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL); alert.getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL);
break; break;
default:
throw new IllegalArgumentException("Unrecognized message box option " + option);
} }
Optional<ButtonType> buttonType = alert.showAndWait(); Optional<ButtonType> buttonType = alert.showAndWait();
if (!buttonType.isPresent()) return CLOSED_OPTION; if (!buttonType.isPresent()) return CLOSED_OPTION;

View File

@@ -76,6 +76,8 @@ public final class MessageDialogPane extends StackPane {
case MessageBox.QUESTION_MESSAGE: case MessageBox.QUESTION_MESSAGE:
graphic.setGraphic(SVG.helpCircle("black", 40, 40)); graphic.setGraphic(SVG.helpCircle("black", 40, 40));
break; break;
default:
throw new IllegalArgumentException("Unrecognized message box message type " + type);
} }
} }

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hmcl.upgrade; package org.jackhuang.hmcl.upgrade;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Main;
@@ -84,10 +85,10 @@ public class AppDataUpgrader extends IUpgrader {
} }
} }
} }
} catch (JsonSyntaxException ex) { } catch (JsonParseException ex) {
f.delete(); f.delete();
} catch (IOException | PrivilegedActionException t) { } catch (IOException | PrivilegedActionException t) {
Logging.LOG.log(Level.SEVERE, "Failed to execute newer version application", t); Logging.LOG.log(Level.SEVERE, "Unable to execute newer version application", t);
} }
} }

View File

@@ -25,6 +25,7 @@ import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession;
import org.jackhuang.hmcl.game.Arguments; import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.task.GetTask; import org.jackhuang.hmcl.task.GetTask;
import org.jackhuang.hmcl.util.Charsets;
import org.jackhuang.hmcl.util.ExceptionalSupplier; import org.jackhuang.hmcl.util.ExceptionalSupplier;
import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.NetworkUtils; import org.jackhuang.hmcl.util.NetworkUtils;
@@ -68,7 +69,7 @@ public class AuthlibInjectorAccount extends YggdrasilAccount {
Arguments arguments = Arguments.addJVMArguments(null, arg); Arguments arguments = Arguments.addJVMArguments(null, arg);
if (flag.get()) if (flag.get())
arguments = Arguments.addJVMArguments(arguments, "-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()))); arguments = Arguments.addJVMArguments(arguments, "-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()), Charsets.UTF_8));
return info.setArguments(arguments); return info.setArguments(arguments);
} catch (Exception e) { } catch (Exception e) {

View File

@@ -77,6 +77,6 @@ public class RemoteVersion<T> implements Comparable<RemoteVersion<T>> {
@Override @Override
public int compareTo(RemoteVersion<T> o) { public int compareTo(RemoteVersion<T> o) {
// newer versions are smaller than older versions // newer versions are smaller than older versions
return -VersionNumber.asVersion(selfVersion).compareTo(VersionNumber.asVersion(o.selfVersion)); return VersionNumber.asVersion(o.selfVersion).compareTo(VersionNumber.asVersion(selfVersion));
} }
} }

View File

@@ -72,7 +72,7 @@ public final class GameVersionList extends VersionList<GameRemoteVersionTag> {
@Override @Override
public int compareTo(RemoteVersion<GameRemoteVersionTag> o) { public int compareTo(RemoteVersion<GameRemoteVersionTag> o) {
return -getTag().getTime().compareTo(o.getTag().getTime()); return o.getTag().getTime().compareTo(getTag().getTime());
} }
} }
} }

View File

@@ -17,16 +17,47 @@
*/ */
package org.jackhuang.hmcl.event; package org.jackhuang.hmcl.event;
import java.util.EventObject; import java.util.Objects;
/** /**
* *
* @author huangyuhui * @author huangyuhui
*/ */
public class Event extends EventObject { public class Event {
/**
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws NullPointerException if source is null.
*/
public Event(Object source) { public Event(Object source) {
super(source); Objects.requireNonNull(source);
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this Event.
*
* @return A a String representation of this Event.
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
} }
private boolean canceled; private boolean canceled;

View File

@@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.io.PipedInputStream; import java.io.PipedInputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -114,6 +115,8 @@ final class Log4jHandler extends Thread {
private class Log4jHandlerImpl extends DefaultHandler { private class Log4jHandlerImpl extends DefaultHandler {
private final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
private String date = "", thread = "", logger = ""; private String date = "", thread = "", logger = "";
private StringBuilder message; private StringBuilder message;
private Log4jLevel level; private Log4jLevel level;
@@ -124,8 +127,8 @@ final class Log4jHandler extends Thread {
switch (localName) { switch (localName) {
case "log4j_Event": case "log4j_Event":
message = new StringBuilder(); message = new StringBuilder();
Date d = new Date(Long.valueOf(attributes.getValue("timestamp"))); Date d = new Date(Long.parseLong(attributes.getValue("timestamp")));
date = Constants.DEFAULT_DATE_FORMAT.format(d); date = format.format(d);
try { try {
level = Log4jLevel.valueOf(attributes.getValue("level")); level = Log4jLevel.valueOf(attributes.getValue("level"));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {

View File

@@ -23,6 +23,7 @@ import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import java.io.File; import java.io.File;
import java.util.Objects;
/** /**
* *
@@ -125,6 +126,16 @@ public final class ModInfo implements Comparable<ModInfo> {
return getFileName().compareTo(o.getFileName()); return getFileName().compareTo(o.getFileName());
} }
@Override
public boolean equals(Object obj) {
return obj instanceof ModInfo && Objects.equals(getFileName(), ((ModInfo) obj).getFileName());
}
@Override
public int hashCode() {
return Objects.hash(getFileName());
}
public static boolean isFileMod(File file) { public static boolean isFileMod(File file) {
String name = file.getName(); String name = file.getName();
if (isDisabled(file)) if (isDisabled(file))

View File

@@ -126,10 +126,7 @@ public class FileDownloadTask extends Task {
if (repeat > 0) { if (repeat > 0) {
FailedEvent<URL> event = new FailedEvent<>(this, repeat, currentURL); FailedEvent<URL> event = new FailedEvent<>(this, repeat, currentURL);
onFailed.fireEvent(event); onFailed.fireEvent(event);
if (!currentURL.equals(event.getNewResult())) { currentURL = event.getNewResult();
Logging.LOG.log(Level.FINE, "Switch from {0} to {1}", new Object[] { currentURL, event.getNewResult() });
currentURL = event.getNewResult();
}
} }
if (Thread.interrupted()) { if (Thread.interrupted()) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();

View File

@@ -19,10 +19,7 @@ package org.jackhuang.hmcl.task;
import org.jackhuang.hmcl.util.ExceptionalRunnable; import org.jackhuang.hmcl.util.ExceptionalRunnable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -84,8 +81,9 @@ class SchedulerImpl extends Scheduler {
} }
@Override @Override
public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException { public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
latch.await(timeout, unit); if (!latch.await(timeout, unit))
throw new TimeoutException();
return getImpl(); return getImpl();
} }
}; };

View File

@@ -52,8 +52,6 @@ public final class Constants {
public static final String DEFAULT_VERSION_DOWNLOAD_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/"; public static final String DEFAULT_VERSION_DOWNLOAD_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/";
public static final String DEFAULT_INDEX_URL = "http://s3.amazonaws.com/Minecraft.Download/indexes/"; public static final String DEFAULT_INDEX_URL = "http://s3.amazonaws.com/Minecraft.Download/indexes/";
public static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("HH:mm:ss");
public static Consumer<Runnable> UI_THREAD_SCHEDULER = s -> Schedulers.computation().schedule(s::run); public static Consumer<Runnable> UI_THREAD_SCHEDULER = s -> Schedulers.computation().schedule(s::run);
public static final Consumer<Runnable> SWING_UI_THREAD_SCHEDULER = s -> { public static final Consumer<Runnable> SWING_UI_THREAD_SCHEDULER = s -> {

View File

@@ -107,14 +107,14 @@ public final class JavaVersion implements Serializable {
try { try {
Process process = new ProcessBuilder(actualFile.getAbsolutePath(), "-version").start(); Process process = new ProcessBuilder(actualFile.getAbsolutePath(), "-version").start();
process.waitFor(); process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
String line; for (String line; (line = reader.readLine()) != null; ) {
while ((line = reader.readLine()) != null) { Matcher m = REGEX.matcher(line);
Matcher m = REGEX.matcher(line); if (m.find())
if (m.find()) version = m.group("version");
version = m.group("version"); if (line.contains("64-Bit"))
if (line.contains("64-Bit")) platform = Platform.BIT_64;
platform = Platform.BIT_64; }
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new IOException("Interrupted scanning the java version.", e); throw new IOException("Interrupted scanning the java version.", e);
@@ -217,11 +217,11 @@ public final class JavaVersion implements Serializable {
Process process = Runtime.getRuntime().exec(cmd); Process process = Runtime.getRuntime().exec(cmd);
process.waitFor(); process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line; for (String line; (line = reader.readLine()) != null; )
while ((line = reader.readLine()) != null) if (line.startsWith(location) && !line.equals(location))
if (line.startsWith(location) && !line.equals(location)) res.add(line);
res.add(line); }
return res; return res;
} }
@@ -241,22 +241,22 @@ public final class JavaVersion implements Serializable {
Process process = Runtime.getRuntime().exec(cmd); Process process = Runtime.getRuntime().exec(cmd);
process.waitFor(); process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line; for (String line; (line = reader.readLine()) != null; )
while ((line = reader.readLine()) != null) if (StringUtils.isNotBlank(line)) {
if (StringUtils.isNotBlank(line)) { if (last && line.trim().startsWith(name)) {
if (last && line.trim().startsWith(name)) { int begins = line.indexOf(name);
int begins = line.indexOf(name); if (begins > 0) {
if (begins > 0) { String s2 = line.substring(begins + name.length());
String s2 = line.substring(begins + name.length()); begins = s2.indexOf("REG_SZ");
begins = s2.indexOf("REG_SZ"); if (begins > 0)
if (begins > 0) return s2.substring(begins + "REG_SZ".length()).trim();
return s2.substring(begins + "REG_SZ".length()).trim(); }
} }
if (location.equals(line.trim()))
last = true;
} }
if (location.equals(line.trim())) }
last = true;
}
return null; return null;
} }
} }

View File

@@ -47,6 +47,11 @@ public final class Lang {
return map; return map;
} }
@SafeVarargs
public static <T> List<T> immutableListOf(T... elements) {
return Collections.unmodifiableList(Arrays.asList(elements));
}
public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Supplier<V> computingFunction) { public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Supplier<V> computingFunction) {
V value = map.get(key); V value = map.get(key);
if (value == null) { if (value == null) {

View File

@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.logging.*; import java.util.logging.*;
@@ -55,10 +56,11 @@ public final class Logging {
static final class DefaultFormatter extends Formatter { static final class DefaultFormatter extends Formatter {
static final DefaultFormatter INSTANCE = new DefaultFormatter(); static final DefaultFormatter INSTANCE = new DefaultFormatter();
private final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
@Override @Override
public String format(LogRecord record) { public String format(LogRecord record) {
String date = Constants.DEFAULT_DATE_FORMAT.format(new Date(record.getMillis())); String date = format.format(new Date(record.getMillis()));
String log = String.format("[%s] [%s.%s/%s] %s%n", String log = String.format("[%s] [%s.%s/%s] %s%n",
date, record.getSourceClassName(), record.getSourceMethodName(), date, record.getSourceClassName(), record.getSourceMethodName(),
record.getLevel().getName(), MessageFormat.format(record.getMessage(), record.getParameters()) record.getLevel().getName(), MessageFormat.format(record.getMessage(), record.getParameters())