Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57018bef47 | ||
|
|
0b65431044 | ||
|
|
991729b684 | ||
|
|
1605eb1775 | ||
|
|
94ccee0b76 | ||
|
|
8b94fe5b0b | ||
|
|
abec1abcff | ||
|
|
127938fa38 | ||
|
|
1187ae4f04 | ||
|
|
8efdc536ee | ||
|
|
78f080b6cc | ||
|
|
cc8bcfd924 | ||
|
|
806ca3f64a | ||
|
|
4a16fa13ee | ||
|
|
b88d7c4fd2 | ||
|
|
c0838468b1 | ||
|
|
90cfe3d0b7 | ||
|
|
baf1d22bc4 | ||
|
|
7ca5744559 | ||
|
|
57e728991b | ||
|
|
e08ba4d421 |
No files matched your search
@@ -27,7 +27,7 @@ S = ';'
|
||||
MOD_SEPARATOR = ','
|
||||
|
||||
CURSEFORGE_PATTERN1 = re.compile(
|
||||
r'^/minecraft/(mc-mods|modpacks|customization|mc-addons|customization/configuration)/+(?P<modid>[\w-]+)(/(.*?))?$')
|
||||
r'^/(minecraft|Minecraft|minecraft-bedrock)/(mc-mods|modpacks|customization|mc-addons|texture-packs|customization/configuration|addons)/+(?P<modid>[\w-]+)(/(.*?))?$')
|
||||
CURSEFORGE_PATTERN2 = re.compile(
|
||||
r'^/projects/(?P<modid>[\w-]+)(/(.*?))?$')
|
||||
CURSEFORGE_PATTERN3 = re.compile(
|
||||
@@ -58,30 +58,6 @@ def parseMcmod(url):
|
||||
return match.group('modid')
|
||||
return ''
|
||||
|
||||
|
||||
MCBBS_HTML_PATTERN = re.compile(r'/+thread-(?P<modid>\d+)-(\d+)-(\d+).html')
|
||||
MCBBS_PHP_PATTERN = re.compile(r'')
|
||||
|
||||
|
||||
def parseMcbbs(url):
|
||||
res = urlparse(url)
|
||||
if res.scheme not in ['http', 'https']:
|
||||
return ''
|
||||
if res.netloc != 'www.mcbbs.net':
|
||||
return ''
|
||||
match = MCBBS_HTML_PATTERN.match(res.path)
|
||||
if match:
|
||||
return match.group('modid')
|
||||
|
||||
query = parse_qs(res.query)
|
||||
|
||||
if res.path == '/forum.php':
|
||||
if 'mod' in query and 'tid' in query and query['mod'] == ['viewthread']:
|
||||
return query['tid']
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
skip = [
|
||||
'Minecraft',
|
||||
'The Building Game'
|
||||
@@ -111,12 +87,11 @@ if __name__ == '__main__':
|
||||
exit(1)
|
||||
|
||||
black_lists = [
|
||||
'Master Chef'
|
||||
'Wood Converter'
|
||||
]
|
||||
|
||||
curseforge_id = ''
|
||||
mcmod_id = ''
|
||||
mcbbs_id = ''
|
||||
links = mod['links']['list']
|
||||
if 'curseforge' in links and links['curseforge'] and sub_name not in black_lists and chinese_name not in black_lists:
|
||||
for link in links['curseforge']:
|
||||
@@ -131,11 +106,6 @@ if __name__ == '__main__':
|
||||
if mcmod_id == '':
|
||||
print('Error mcmod ' + chinese_name)
|
||||
exit(1)
|
||||
if 'mcbbs' in links and links['mcbbs']:
|
||||
mcbbs_id = parseMcbbs(links['mcbbs'][0]['url'])
|
||||
if mcbbs_id == '':
|
||||
print('Error mcbbs ' + chinese_name)
|
||||
exit(1)
|
||||
|
||||
mod_id = []
|
||||
if 'modid' in mod and 'list' in mod['modid']:
|
||||
@@ -148,6 +118,6 @@ if __name__ == '__main__':
|
||||
mod_ids = MOD_SEPARATOR.join([str(id) for id in mod_id])
|
||||
|
||||
outfile.write(
|
||||
f'{curseforge_id}{S}{mcmod_id}{S}{mcbbs_id}{S}{mod_ids}{S}{chinese_name}{S}{sub_name}{S}{abbr}\n')
|
||||
f'{curseforge_id}{S}{mcmod_id}{S}{mod_ids}{S}{chinese_name}{S}{sub_name}{S}{abbr}\n')
|
||||
|
||||
print('Success!')
|
||||
@@ -12,14 +12,10 @@ import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Scale;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SkinCanvas extends Group {
|
||||
|
||||
public static final Image ALEX = FXUtils.newBuiltinImage("/assets/img/skin/alex.png");
|
||||
public static final Image STEVE = FXUtils.newBuiltinImage("/assets/img/skin/steve.png");
|
||||
|
||||
public static final SkinCube ALEX_LARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 32F / 64F, 48F / 64F, 0F, true);
|
||||
public static final SkinCube ALEX_RARM = new SkinCube(3, 12, 4, 14F / 64F, 16F / 64F, 40F / 64F, 16F / 64F, 0F, true);
|
||||
|
||||
@@ -152,10 +148,6 @@ public class SkinCanvas extends Group {
|
||||
capeGroup.setVisible(hasCape);
|
||||
}
|
||||
|
||||
public SkinCanvas(double preW, double preH) {
|
||||
this(STEVE, preW, preH, true);
|
||||
}
|
||||
|
||||
public SkinCanvas(Image skin, double preW, double preH, boolean msaa) {
|
||||
this.skin = skin;
|
||||
this.preW = preW;
|
||||
|
||||
@@ -25,9 +25,6 @@ import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.DataFormat;
|
||||
import javafx.stage.Stage;
|
||||
import org.jackhuang.hmcl.auth.offline.Skin;
|
||||
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.setting.ConfigHolder;
|
||||
import org.jackhuang.hmcl.setting.SambaException;
|
||||
import org.jackhuang.hmcl.task.AsyncTaskExecutor;
|
||||
@@ -53,13 +50,10 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class Launcher extends Application {
|
||||
@@ -71,14 +65,12 @@ public final class Launcher extends Application {
|
||||
|
||||
CookieHandler.setDefault(COOKIE_MANAGER);
|
||||
|
||||
register();
|
||||
|
||||
LOG.info("JavaFX Version: " + System.getProperty("javafx.runtime.version"));
|
||||
try {
|
||||
Object pipeline = Class.forName("com.sun.prism.GraphicsPipeline").getMethod("getPipeline").invoke(null);
|
||||
LOG.info("Prism pipeline: " + (pipeline == null ? "null" : pipeline.getClass().getName()));
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to get prism pipeline", e);
|
||||
LOG.warning("Failed to get prism pipeline", e);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -87,7 +79,7 @@ public final class Launcher extends Application {
|
||||
} catch (SambaException ignored) {
|
||||
Main.showWarningAndContinue(i18n("fatal.samba"));
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Failed to load config", e);
|
||||
LOG.error("Failed to load config", e);
|
||||
checkConfigInTempDir();
|
||||
checkConfigOwner();
|
||||
Main.showErrorAndExit(i18n("fatal.config_loading_failure", ConfigHolder.configLocation().getParent()));
|
||||
@@ -128,45 +120,6 @@ public final class Launcher extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
private static void register() {
|
||||
Skin.registerDefaultSkinLoader((type) -> {
|
||||
switch (type) {
|
||||
case ALEX:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/alex.png");
|
||||
case ARI:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/ari.png");
|
||||
case EFE:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/efe.png");
|
||||
case KAI:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/kai.png");
|
||||
case MAKENA:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/makena.png");
|
||||
case NOOR:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/noor.png");
|
||||
case STEVE:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/steve.png");
|
||||
case SUNNY:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/sunny.png");
|
||||
case ZURI:
|
||||
return Skin.class.getResourceAsStream("/assets/img/skin/zuri.png");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
RemoteMod.registerEmptyRemoteMod(new RemoteMod("", "", i18n("mods.broken_dependency.title"), i18n("mods.broken_dependency.desc"), new ArrayList<>(), "", "/assets/img/icon@8x.png", new RemoteMod.IMod() {
|
||||
@Override
|
||||
public List<RemoteMod> loadDependencies(RemoteModRepository modRepository) throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RemoteMod.Version> loadVersions(RemoteModRepository modRepository) throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static ButtonType showAlert(AlertType alertType, String contentText, ButtonType... buttons) {
|
||||
return new Alert(alertType, contentText, buttons).showAndWait().orElse(null);
|
||||
}
|
||||
@@ -211,7 +164,7 @@ public final class Launcher extends Application {
|
||||
private static void checkConfigInTempDir() {
|
||||
if (ConfigHolder.isNewlyCreated() && isConfigInTempDir()
|
||||
&& showAlert(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) {
|
||||
System.exit(0);
|
||||
Main.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +177,7 @@ public final class Launcher extends Application {
|
||||
try {
|
||||
owner = Files.getOwner(ConfigHolder.configLocation()).getName();
|
||||
} catch (IOException ioe) {
|
||||
LOG.log(Level.WARNING, "Failed to get file owner", ioe);
|
||||
LOG.warning("Failed to get file owner", ioe);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,17 +202,18 @@ public final class Launcher extends Application {
|
||||
Clipboard.getSystemClipboard()
|
||||
.setContent(Collections.singletonMap(DataFormat.PLAIN_TEXT, command));
|
||||
}
|
||||
System.exit(1);
|
||||
Main.exit(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
super.stop();
|
||||
Controllers.onApplicationStop();
|
||||
LOG.shutdown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (UpdateHandler.processArguments(args)) {
|
||||
LOG.shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -277,6 +231,7 @@ public final class Launcher extends Application {
|
||||
LOG.info("Current Directory: " + System.getProperty("user.dir"));
|
||||
LOG.info("HMCL Directory: " + Metadata.HMCL_DIRECTORY);
|
||||
LOG.info("HMCL Jar Path: " + Lang.requireNonNullElse(JarUtils.thisJarPath(), "Not Found"));
|
||||
LOG.info("HMCL Log File: " + Lang.requireNonNullElse(LOG.getLogFile(), "In Memory"));
|
||||
LOG.info("Memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
|
||||
LOG.info("Physical memory: " + OperatingSystem.TOTAL_MEMORY + " MB");
|
||||
LOG.info("Metaspace: " + ManagementFactory.getMemoryPoolMXBeans().stream()
|
||||
|
||||
@@ -21,7 +21,6 @@ import javafx.application.Platform;
|
||||
import javafx.scene.control.Alert;
|
||||
import org.jackhuang.hmcl.ui.AwtUtils;
|
||||
import org.jackhuang.hmcl.util.FractureiserDetector;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.SelfDependencyPatcher;
|
||||
import org.jackhuang.hmcl.ui.SwingUtils;
|
||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||
@@ -43,10 +42,9 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class Main {
|
||||
@@ -55,10 +53,12 @@ public final class Main {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("java.net.useSystemProxies", "true");
|
||||
System.setProperty("javafx.autoproxy.disable", "true");
|
||||
System.getProperties().putIfAbsent("java.net.useSystemProxies", "true");
|
||||
System.getProperties().putIfAbsent("javafx.autoproxy.disable", "true");
|
||||
System.getProperties().putIfAbsent("http.agent", "HMCL/" + Metadata.VERSION);
|
||||
|
||||
LOG.start(Metadata.HMCL_DIRECTORY.resolve("logs"));
|
||||
|
||||
checkDirectoryPath();
|
||||
|
||||
if (JavaVersion.CURRENT_JAVA.getParsedVersion() < 9)
|
||||
@@ -68,8 +68,6 @@ public final class Main {
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX)
|
||||
initIcon();
|
||||
|
||||
Logging.start(Metadata.HMCL_DIRECTORY.resolve("logs"));
|
||||
|
||||
checkJavaFX();
|
||||
verifyJavaFX();
|
||||
detectFractureiser();
|
||||
@@ -77,6 +75,11 @@ public final class Main {
|
||||
Launcher.main(args);
|
||||
}
|
||||
|
||||
public static void exit(int exitCode) {
|
||||
LOG.shutdown();
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
private static void initIcon() {
|
||||
java.awt.Image image = java.awt.Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/assets/img/icon@8x.png"));
|
||||
AwtUtils.setAppleIcon(image);
|
||||
@@ -93,7 +96,7 @@ public final class Main {
|
||||
|
||||
private static void detectFractureiser() {
|
||||
if (FractureiserDetector.detect()) {
|
||||
LOG.log(Level.SEVERE, "Detected that this computer is infected by fractureiser");
|
||||
LOG.error("Detected that this computer is infected by fractureiser");
|
||||
showErrorAndExit(i18n("fatal.fractureiser"));
|
||||
}
|
||||
}
|
||||
@@ -102,14 +105,14 @@ public final class Main {
|
||||
try {
|
||||
SelfDependencyPatcher.patch();
|
||||
} catch (SelfDependencyPatcher.PatchException e) {
|
||||
LOG.log(Level.SEVERE, "unable to patch JVM", e);
|
||||
LOG.error("unable to patch JVM", e);
|
||||
showErrorAndExit(i18n("fatal.javafx.missing"));
|
||||
} catch (SelfDependencyPatcher.IncompatibleVersionException e) {
|
||||
LOG.log(Level.SEVERE, "unable to patch JVM", e);
|
||||
LOG.error("unable to patch JVM", e);
|
||||
showErrorAndExit(i18n("fatal.javafx.incompatible"));
|
||||
} catch (CancellationException e) {
|
||||
LOG.log(Level.SEVERE, "User cancels downloading JavaFX", e);
|
||||
System.exit(0);
|
||||
LOG.error("User cancels downloading JavaFX", e);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +139,13 @@ public final class Main {
|
||||
try {
|
||||
if (Platform.isFxApplicationThread()) {
|
||||
new Alert(Alert.AlertType.ERROR, message).showAndWait();
|
||||
System.exit(1);
|
||||
exit(1);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
SwingUtils.showErrorDialog(message);
|
||||
System.exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,7 +195,7 @@ public final class Main {
|
||||
LOG.info("Added Lets Encrypt root certificates as additional trust");
|
||||
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException |
|
||||
KeyManagementException e) {
|
||||
LOG.log(Level.SEVERE, "Failed to load lets encrypt certificate. Expect problems", e);
|
||||
LOG.error("Failed to load lets encrypt certificate. Expect problems", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jackhuang.hmcl.countly;
|
||||
|
||||
import org.jackhuang.hmcl.Metadata;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
@@ -13,6 +12,7 @@ import java.util.Map;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class CrashReport {
|
||||
|
||||
@@ -59,7 +59,7 @@ public class CrashReport {
|
||||
pair("_ram_current", getMemoryAvailable()),
|
||||
pair("_ram_total", Runtime.getRuntime().maxMemory() / BYTES_IN_MB),
|
||||
pair("_error", stackTrace),
|
||||
pair("_logs", Logging.getLogs()),
|
||||
pair("_logs", LOG.getLogs()),
|
||||
pair("_name", throwable.getLocalizedMessage()),
|
||||
pair("_nonfatal", nonFatal)
|
||||
);
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jackhuang.hmcl.Metadata;
|
||||
import org.jackhuang.hmcl.auth.AuthInfo;
|
||||
import org.jackhuang.hmcl.launch.DefaultLauncher;
|
||||
import org.jackhuang.hmcl.launch.ProcessListener;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||
@@ -29,9 +28,9 @@ import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
@@ -72,7 +71,7 @@ public final class HMCLGameLauncher extends DefaultLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
if (I18n.getCurrentLocale().getLocale() != Locale.CHINA) {
|
||||
if (!I18n.isUseChinese()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ public final class HMCLGameLauncher extends DefaultLauncher {
|
||||
try {
|
||||
FileUtils.writeText(optionsFile, String.format("lang:%s\n", lang));
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to generate options.txt", e);
|
||||
LOG.warning("Unable to generate options.txt", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,11 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public class HMCLGameRepository extends DefaultGameRepository {
|
||||
@@ -124,7 +123,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
if (!file.exists() && !versions.isEmpty())
|
||||
FileUtils.writeText(file, PROFILE);
|
||||
} catch (IOException ex) {
|
||||
LOG.log(Level.WARNING, "Unable to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex);
|
||||
LOG.warning("Unable to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex);
|
||||
}
|
||||
|
||||
// https://github.com/HMCL-dev/HMCL/issues/938
|
||||
@@ -259,8 +258,50 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
return vs;
|
||||
}
|
||||
|
||||
public File getVersionIconFile(String id) {
|
||||
return new File(getVersionRoot(id), "icon.png");
|
||||
public Optional<File> getVersionIconFile(String id) {
|
||||
File root = getVersionRoot(id);
|
||||
|
||||
File iconFile = new File(root, "icon.png");
|
||||
if (iconFile.exists()) {
|
||||
return Optional.of(iconFile);
|
||||
}
|
||||
|
||||
iconFile = new File(root, "icon.jpg");
|
||||
if (iconFile.exists()) {
|
||||
return Optional.of(iconFile);
|
||||
}
|
||||
|
||||
iconFile = new File(root, "icon.bmp");
|
||||
if (iconFile.exists()) {
|
||||
return Optional.of(iconFile);
|
||||
}
|
||||
|
||||
iconFile = new File(root, "icon.gif");
|
||||
if (iconFile.exists()) {
|
||||
return Optional.of(iconFile);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void setVersionIconFile(String id, File iconFile) throws IOException {
|
||||
String ext = FileUtils.getExtension(iconFile).toLowerCase(Locale.ROOT);
|
||||
if (!ext.equals("png") && !ext.equals("jpg") && !ext.equals("bmp") && !ext.equals("gif")) {
|
||||
throw new IllegalArgumentException("Unsupported icon file: " + ext);
|
||||
}
|
||||
|
||||
deleteIconFile(id);
|
||||
|
||||
FileUtils.copyFile(iconFile, new File(getVersionRoot(id), "icon." + ext));
|
||||
}
|
||||
|
||||
public void deleteIconFile(String id) {
|
||||
File root = getVersionRoot(id);
|
||||
|
||||
new File(root, "icon.png").delete();
|
||||
new File(root, "icon.jpg").delete();
|
||||
new File(root, "icon.bmp").delete();
|
||||
new File(root, "icon.gif").delete();
|
||||
}
|
||||
|
||||
public Image getVersionIconImage(String id) {
|
||||
@@ -272,12 +313,12 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
|
||||
if (iconType == VersionIconType.DEFAULT) {
|
||||
Version version = getVersion(id).resolve(this);
|
||||
File iconFile = getVersionIconFile(id);
|
||||
if (iconFile.exists()) {
|
||||
try (InputStream inputStream = new FileInputStream(iconFile)) {
|
||||
Optional<File> iconFile = getVersionIconFile(id);
|
||||
if (iconFile.isPresent()) {
|
||||
try (InputStream inputStream = new FileInputStream(iconFile.get())) {
|
||||
return new Image(inputStream);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to load version icon of " + id, e);
|
||||
LOG.warning("Failed to load version icon of " + id, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +357,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
FileUtils.writeText(file, GSON.toJson(localVersionSettings.get(id)));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Unable to save version setting of " + id, e);
|
||||
LOG.error("Unable to save version setting of " + id, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,13 +60,12 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||
import static org.jackhuang.hmcl.util.Lang.resolveException;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -112,7 +111,7 @@ public final class LauncherHelper {
|
||||
public void launch() {
|
||||
FXUtils.checkFxUserThread();
|
||||
|
||||
Logging.LOG.info("Launching game version: " + selectedVersion);
|
||||
LOG.info("Launching game version: " + selectedVersion);
|
||||
|
||||
Controllers.dialog(launchingStepsPane);
|
||||
launch0();
|
||||
@@ -333,7 +332,8 @@ public final class LauncherHelper {
|
||||
}
|
||||
|
||||
private static Task<JavaVersion> checkGameState(Profile profile, VersionSetting setting, Version version) {
|
||||
GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(profile.getRepository().getGameVersion(version));
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version, profile.getRepository().getGameVersion(version).orElse(null));
|
||||
GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(analyzer.getVersion(LibraryAnalyzer.LibraryType.MINECRAFT));
|
||||
|
||||
if (setting.isNotCheckJVM()) {
|
||||
return Task.composeAsync(() -> setting.getJavaVersion(gameVersion, version))
|
||||
@@ -388,7 +388,7 @@ public final class LauncherHelper {
|
||||
future.complete(downloadedJavaVersion);
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
LOG.log(Level.WARNING, "Failed to download java", throwable);
|
||||
LOG.warning("Failed to download java", throwable);
|
||||
Controllers.confirm(i18n("launch.failed.no_accepted_java"), i18n("message.warning"), MessageType.WARNING, continueAction, () -> {
|
||||
future.completeExceptionally(new CancellationException("No accepted java"));
|
||||
});
|
||||
@@ -417,7 +417,6 @@ public final class LauncherHelper {
|
||||
JavaVersionConstraint violatedMandatoryConstraint = null;
|
||||
List<JavaVersionConstraint> violatedSuggestedConstraints = null;
|
||||
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version, gameVersion.toString());
|
||||
for (JavaVersionConstraint constraint : JavaVersionConstraint.ALL) {
|
||||
if (constraint.appliesToVersion(gameVersion, version, javaVersion, analyzer)) {
|
||||
if (!constraint.checkJava(gameVersion, version, javaVersion)) {
|
||||
@@ -452,7 +451,7 @@ public final class LauncherHelper {
|
||||
future.complete(downloadedJavaVersion);
|
||||
}, Schedulers.javafx())
|
||||
.whenCompleteAsync((result, throwable) -> {
|
||||
LOG.log(Level.WARNING, "Failed to download java", throwable);
|
||||
LOG.warning("Failed to download java", throwable);
|
||||
breakAction.run();
|
||||
}, Schedulers.javafx());
|
||||
return Task.fromCompletableFuture(future);
|
||||
@@ -605,7 +604,7 @@ public final class LauncherHelper {
|
||||
.thenAcceptAsync(future::complete)
|
||||
.exceptionally(throwable -> {
|
||||
Throwable resolvedException = resolveException(throwable);
|
||||
LOG.log(Level.WARNING, "Failed to download java", throwable);
|
||||
LOG.warning("Failed to download java", throwable);
|
||||
if (!(resolvedException instanceof CancellationException)) {
|
||||
Controllers.dialog(DownloadProviders.localizeErrorMessage(resolvedException), i18n("install.failed"));
|
||||
}
|
||||
@@ -644,11 +643,11 @@ public final class LauncherHelper {
|
||||
try {
|
||||
return Task.completed(account.logIn());
|
||||
} catch (CredentialExpiredException e) {
|
||||
LOG.log(Level.INFO, "Credential has expired", e);
|
||||
LOG.info("Credential has expired", e);
|
||||
|
||||
return Task.completed(DialogController.logIn(account));
|
||||
} catch (AuthenticationException e) {
|
||||
LOG.log(Level.WARNING, "Authentication failed, try skipping refresh", e);
|
||||
LOG.warning("Authentication failed, try skipping refresh", e);
|
||||
|
||||
CompletableFuture<Task<AuthInfo>> future = new CompletableFuture<>();
|
||||
runInFX(() -> {
|
||||
|
||||
@@ -27,10 +27,9 @@ import org.jackhuang.hmcl.util.StringUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public abstract class LocalizedRemoteModRepository implements RemoteModRepository {
|
||||
private static final int CONTAIN_CHINESE_WEIGHT = 10;
|
||||
@@ -69,7 +68,7 @@ public abstract class LocalizedRemoteModRepository implements RemoteModRepositor
|
||||
SearchResult searchResult = getBackedRemoteModRepository().search(gameVersion, category, pageOffset, pageSize, String.join(" ", englishSearchFiltersSet), getBackedRemoteModRepositorySortOrder(), sortOrder);
|
||||
for (Iterator<RemoteMod> iterator = searchResult.getUnsortedResults().iterator(); iterator.hasNext(); ) {
|
||||
if (chineseIndex > englishIndex) {
|
||||
LOG.log(Level.WARNING, "Too many search results! Are the backed remote mod repository broken? Or are the API broken?");
|
||||
LOG.warning("Too many search results! Are the backed remote mod repository broken? Or are the API broken?");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
@@ -35,9 +35,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class LogExporter {
|
||||
private LogExporter() {
|
||||
@@ -70,9 +69,9 @@ public final class LogExporter {
|
||||
processLogs(runDirectory, "*.log", "runDirectory", zipper);
|
||||
processLogs(runDirectory.resolve("crash-reports"), "*.txt", "crash-reports", zipper);
|
||||
|
||||
zipper.putTextFile(Logging.getLogs(), "hmcl.log");
|
||||
zipper.putTextFile(LOG.getLogs(), "hmcl.log");
|
||||
zipper.putTextFile(logs, "minecraft.log");
|
||||
zipper.putTextFile(Logging.filterForbiddenToken(launchScript), OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "launch.bat" : "launch.sh");
|
||||
zipper.putTextFile(Logger.filterForbiddenToken(launchScript), OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "launch.bat" : "launch.sh");
|
||||
|
||||
for (String id : versions) {
|
||||
Path versionJson = baseDirectory.resolve("versions").resolve(id).resolve(id + ".json");
|
||||
@@ -95,16 +94,16 @@ public final class LogExporter {
|
||||
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
|
||||
if (time.toMillis() >= processStartTime) {
|
||||
try {
|
||||
String crashLog = Logging.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
|
||||
String crashLog = Logger.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
|
||||
zipper.putTextFile(crashLog, file.getFileName().toString());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read log file: " + file, e);
|
||||
LOG.warning("Failed to read log file: " + file, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to find any log on " + logDirectory, e);
|
||||
LOG.warning("Failed to find any log on " + logDirectory, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import org.jackhuang.hmcl.auth.OAuth;
|
||||
import org.jackhuang.hmcl.event.Event;
|
||||
import org.jackhuang.hmcl.event.EventManager;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
import org.jackhuang.hmcl.util.io.JarUtils;
|
||||
@@ -34,10 +33,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
|
||||
@@ -80,7 +79,7 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
|
||||
try {
|
||||
session.parseBody(files);
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Failed to read post data", e);
|
||||
LOG.warning("Failed to read post data", e);
|
||||
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_HTML, "");
|
||||
} catch (ResponseException re) {
|
||||
return newFixedLengthResponse(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
|
||||
@@ -97,7 +96,7 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
|
||||
idToken = query.get("id_token");
|
||||
future.complete(query.get("code"));
|
||||
} else {
|
||||
Logging.LOG.warning("Error: " + parameters);
|
||||
LOG.warning("Error: " + parameters);
|
||||
future.completeExceptionally(new AuthenticationException("failed to authenticate"));
|
||||
}
|
||||
|
||||
@@ -106,7 +105,7 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
|
||||
html = IOUtils.readFullyAsString(OAuthServer.class.getResourceAsStream("/assets/microsoft_auth.html"))
|
||||
.replace("%close-page%", i18n("account.methods.microsoft.close_page"));
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Failed to load html");
|
||||
LOG.error("Failed to load html", e);
|
||||
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_HTML, "");
|
||||
}
|
||||
thread(() -> {
|
||||
@@ -114,7 +113,7 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
|
||||
Thread.sleep(1000);
|
||||
stop();
|
||||
} catch (InterruptedException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Failed to sleep for 1 second");
|
||||
LOG.error("Failed to sleep for 1 second");
|
||||
}
|
||||
});
|
||||
return newFixedLengthResponse(Response.Status.OK, "text/html; charset=UTF-8", html);
|
||||
|
||||
@@ -52,13 +52,12 @@ import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
* @author yushijinhun
|
||||
@@ -116,7 +115,7 @@ public final class TexturesLoader {
|
||||
} catch (Exception e) {
|
||||
if (Files.isRegularFile(file)) {
|
||||
// concurrency conflict?
|
||||
LOG.log(Level.WARNING, "Failed to download texture " + texture.getUrl() + ", but the file is available", e);
|
||||
LOG.warning("Failed to download texture " + texture.getUrl() + ", but the file is available", e);
|
||||
} else {
|
||||
throw new IOException("Failed to download texture " + texture.getUrl());
|
||||
}
|
||||
@@ -140,30 +139,42 @@ public final class TexturesLoader {
|
||||
// ====
|
||||
|
||||
// ==== Skins ====
|
||||
private final static Map<TextureModel, LoadedTexture> DEFAULT_SKINS = new EnumMap<>(TextureModel.class);
|
||||
private static final String[] DEFAULT_SKINS = {"alex", "ari", "efe", "kai", "makena", "noor", "steve", "sunny", "zuri"};
|
||||
|
||||
static {
|
||||
loadDefaultSkin("/assets/img/skin/steve.png", TextureModel.STEVE);
|
||||
loadDefaultSkin("/assets/img/skin/alex.png", TextureModel.ALEX);
|
||||
public static Image getDefaultSkinImage() {
|
||||
return FXUtils.newBuiltinImage("/assets/img/skin/wide/steve.png");
|
||||
}
|
||||
|
||||
private static void loadDefaultSkin(String path, TextureModel model) {
|
||||
DEFAULT_SKINS.put(model, new LoadedTexture(FXUtils.newBuiltinImage(path), singletonMap("model", model.modelName)));
|
||||
public static LoadedTexture getDefaultSkin(UUID uuid) {
|
||||
int idx = Math.floorMod(uuid.hashCode(), DEFAULT_SKINS.length * 2);
|
||||
TextureModel model;
|
||||
Image skin;
|
||||
if (idx < DEFAULT_SKINS.length) {
|
||||
model = TextureModel.SLIM;
|
||||
skin = FXUtils.newBuiltinImage("/assets/img/skin/slim/" + DEFAULT_SKINS[idx] + ".png");
|
||||
} else {
|
||||
model = TextureModel.WIDE;
|
||||
skin = FXUtils.newBuiltinImage("/assets/img/skin/wide/" + DEFAULT_SKINS[idx - DEFAULT_SKINS.length] + ".png");
|
||||
}
|
||||
|
||||
return new LoadedTexture(skin, singletonMap("model", model.modelName));
|
||||
}
|
||||
|
||||
public static LoadedTexture getDefaultSkin(TextureModel model) {
|
||||
return DEFAULT_SKINS.get(model);
|
||||
public static TextureModel getDefaultModel(UUID uuid) {
|
||||
return TextureModel.WIDE.modelName.equals(getDefaultSkin(uuid).getMetadata().get("model"))
|
||||
? TextureModel.WIDE
|
||||
: TextureModel.SLIM;
|
||||
}
|
||||
|
||||
public static ObjectBinding<LoadedTexture> skinBinding(YggdrasilService service, UUID uuid) {
|
||||
LoadedTexture uuidFallback = getDefaultSkin(TextureModel.detectUUID(uuid));
|
||||
LoadedTexture uuidFallback = getDefaultSkin(uuid);
|
||||
return BindingMapping.of(service.getProfileRepository().binding(uuid))
|
||||
.map(profile -> profile
|
||||
.flatMap(it -> {
|
||||
try {
|
||||
return YggdrasilService.getTextures(it);
|
||||
} catch (ServerResponseMalformedException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse texture payload", e);
|
||||
LOG.warning("Failed to parse texture payload", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
})
|
||||
@@ -176,7 +187,7 @@ public final class TexturesLoader {
|
||||
try {
|
||||
return loadTexture(texture);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to load texture " + texture.getUrl() + ", using fallback texture", e);
|
||||
LOG.warning("Failed to load texture " + texture.getUrl() + ", using fallback texture", e);
|
||||
return uuidFallback;
|
||||
}
|
||||
}, POOL);
|
||||
@@ -187,7 +198,7 @@ public final class TexturesLoader {
|
||||
}
|
||||
|
||||
public static ObservableValue<LoadedTexture> skinBinding(Account account) {
|
||||
LoadedTexture uuidFallback = getDefaultSkin(TextureModel.detectUUID(account.getUUID()));
|
||||
LoadedTexture uuidFallback = getDefaultSkin(account.getUUID());
|
||||
if (account instanceof OfflineAccount) {
|
||||
OfflineAccount offlineAccount = (OfflineAccount) account;
|
||||
|
||||
@@ -200,7 +211,7 @@ public final class TexturesLoader {
|
||||
if (skin != null) {
|
||||
skin.load(username).setExecutor(POOL).whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
if (exception != null) {
|
||||
LOG.log(Level.WARNING, "Failed to load texture", exception);
|
||||
LOG.warning("Failed to load texture", exception);
|
||||
} else if (result != null && result.getSkin() != null && result.getSkin().getImage() != null) {
|
||||
Map<String, String> metadata;
|
||||
if (result.getModel() != null) {
|
||||
@@ -231,7 +242,7 @@ public final class TexturesLoader {
|
||||
try {
|
||||
return loadTexture(texture);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to load texture " + texture.getUrl() + ", using fallback texture", e);
|
||||
LOG.warning("Failed to load texture " + texture.getUrl() + ", using fallback texture", e);
|
||||
return uuidFallback;
|
||||
}
|
||||
}, POOL);
|
||||
@@ -348,7 +359,7 @@ public final class TexturesLoader {
|
||||
fxAvatarBinding(canvas, skinBinding(account));
|
||||
else {
|
||||
unbindAvatar(canvas);
|
||||
drawAvatar(canvas, getDefaultSkin(TextureModel.detectUUID(account.getUUID())).image);
|
||||
drawAvatar(canvas, getDefaultSkin(account.getUUID()).image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static javafx.collections.FXCollections.observableArrayList;
|
||||
@@ -55,7 +54,7 @@ import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
|
||||
import static org.jackhuang.hmcl.util.Lang.immutableListOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -72,7 +71,7 @@ public final class Accounts {
|
||||
try {
|
||||
((AuthlibInjectorDownloader) AUTHLIB_INJECTOR_DOWNLOADER).checkUpdate();
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to check update for authlib-injector", e);
|
||||
LOG.warning("Failed to check update for authlib-injector", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -178,7 +177,7 @@ public final class Accounts {
|
||||
Config.CONFIG_GSON.fromJson(reader, new TypeToken<List<Map<Object, Object>>>() {
|
||||
}.getType()));
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to load global accounts", e);
|
||||
LOG.warning("Failed to load global accounts", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +189,7 @@ public final class Accounts {
|
||||
FileUtils.saveSafely(globalAccountsFile, json);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Failed to save global accounts", e);
|
||||
LOG.error("Failed to save global accounts", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -209,7 +208,7 @@ public final class Accounts {
|
||||
try {
|
||||
return factory.fromStorage(storage);
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.WARNING, "Failed to load account: " + storage, e);
|
||||
LOG.warning("Failed to load account: " + storage, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -321,7 +320,7 @@ public final class Accounts {
|
||||
try {
|
||||
finalSelected.logIn();
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to log " + finalSelected + " in", e);
|
||||
LOG.warning("Failed to log " + finalSelected + " in", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -335,7 +334,7 @@ public final class Accounts {
|
||||
try {
|
||||
server.fetchMetadataResponse();
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to fetch authlib-injector server metdata: " + server, e);
|
||||
LOG.warning("Failed to fetch authlib-injector server metdata: " + server, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,10 +34,9 @@ import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class AuthlibInjectorServers implements Validation {
|
||||
|
||||
@@ -77,7 +76,7 @@ public final class AuthlibInjectorServers implements Validation {
|
||||
String content = FileUtils.readText(configLocation);
|
||||
configInstance = JsonUtils.GSON.fromJson(content, AuthlibInjectorServers.class);
|
||||
} catch (IOException | JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Malformed authlib-injectors.json", e);
|
||||
LOG.warning("Malformed authlib-injectors.json", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,8 @@ import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class ConfigHolder {
|
||||
|
||||
@@ -81,7 +80,7 @@ public final class ConfigHolder {
|
||||
|
||||
configLocation = locateConfig();
|
||||
|
||||
LOG.log(Level.INFO, "Config location: " + configLocation);
|
||||
LOG.info("Config location: " + configLocation);
|
||||
|
||||
configInstance = loadConfig();
|
||||
configInstance.addListener(source -> markConfigDirty());
|
||||
@@ -91,6 +90,7 @@ public final class ConfigHolder {
|
||||
|
||||
Locale.setDefault(config().getLocalization().getLocale());
|
||||
I18n.setLocale(configInstance.getLocalization());
|
||||
LOG.setLogRetention(globalConfig().getLogRetention());
|
||||
Settings.init();
|
||||
|
||||
if (newlyCreated) {
|
||||
@@ -101,7 +101,7 @@ public final class ConfigHolder {
|
||||
try {
|
||||
Files.setAttribute(configLocation, "dos:hidden", true);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to set hidden attribute of " + configLocation, e);
|
||||
LOG.warning("Failed to set hidden attribute of " + configLocation, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public final class ConfigHolder {
|
||||
ownerChanged = true;
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
LOG.log(Level.WARNING, "Failed to get owner");
|
||||
LOG.warning("Failed to get owner");
|
||||
}
|
||||
try {
|
||||
String content = FileUtils.readText(configLocation);
|
||||
@@ -173,7 +173,7 @@ public final class ConfigHolder {
|
||||
return deserialized;
|
||||
}
|
||||
} catch (JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Malformed config.", e);
|
||||
LOG.warning("Malformed config.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ public final class ConfigHolder {
|
||||
try {
|
||||
writeToConfig(content);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Failed to save config", e);
|
||||
LOG.error("Failed to save config", e);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -218,7 +218,7 @@ public final class ConfigHolder {
|
||||
return deserialized;
|
||||
}
|
||||
} catch (JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Malformed config.", e);
|
||||
LOG.warning("Malformed config.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ public final class ConfigHolder {
|
||||
try {
|
||||
writeToGlobalConfig(content);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Failed to save config", e);
|
||||
LOG.error("Failed to save config", e);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -23,10 +23,9 @@ import org.jackhuang.hmcl.util.StringUtils;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
final class ConfigUpgrader {
|
||||
private ConfigUpgrader() {
|
||||
@@ -48,12 +47,12 @@ final class ConfigUpgrader {
|
||||
}
|
||||
|
||||
if (configVersion > CURRENT_VERSION) {
|
||||
LOG.log(Level.WARNING, String.format("Current HMCL only support the configuration version up to %d. However, the version now is %d.", CURRENT_VERSION, configVersion));
|
||||
LOG.warning(String.format("Current HMCL only support the configuration version up to %d. However, the version now is %d.", CURRENT_VERSION, configVersion));
|
||||
deserialized.setConfigVersion(CURRENT_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.log(Level.INFO, String.format("Updating configuration from %d to %d.", configVersion, CURRENT_VERSION));
|
||||
LOG.info(String.format("Updating configuration from %d to %d.", configVersion, CURRENT_VERSION));
|
||||
Map<?, ?> rawJson = Collections.unmodifiableMap(new Gson().<Map<?, ?>>fromJson(rawContent, Map.class));
|
||||
|
||||
if (configVersion < 1) {
|
||||
|
||||
@@ -49,6 +49,8 @@ public final class GlobalConfig implements Cloneable, Observable {
|
||||
|
||||
private final IntegerProperty platformPromptVersion = new SimpleIntegerProperty();
|
||||
|
||||
private final IntegerProperty logRetention = new SimpleIntegerProperty();
|
||||
|
||||
private final Map<String, Object> unknownFields = new HashMap<>();
|
||||
|
||||
private final transient ObservableHelper helper = new ObservableHelper(this);
|
||||
@@ -100,10 +102,23 @@ public final class GlobalConfig implements Cloneable, Observable {
|
||||
this.platformPromptVersion.set(platformPromptVersion);
|
||||
}
|
||||
|
||||
public int getLogRetention() {
|
||||
return logRetention.get();
|
||||
}
|
||||
|
||||
public IntegerProperty logRetentionProperty() {
|
||||
return logRetention;
|
||||
}
|
||||
|
||||
public void setLogRetention(int logRetention) {
|
||||
this.logRetention.set(logRetention);
|
||||
}
|
||||
|
||||
public static final class Serializer implements JsonSerializer<GlobalConfig>, JsonDeserializer<GlobalConfig> {
|
||||
private static final Set<String> knownFields = new HashSet<>(Arrays.asList(
|
||||
"agreementVersion",
|
||||
"platformPromptVersion"
|
||||
"platformPromptVersion",
|
||||
"logRetention"
|
||||
));
|
||||
|
||||
@Override
|
||||
@@ -115,6 +130,7 @@ public final class GlobalConfig implements Cloneable, Observable {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.add("agreementVersion", context.serialize(src.getAgreementVersion()));
|
||||
jsonObject.add("platformPromptVersion", context.serialize(src.getPlatformPromptVersion()));
|
||||
jsonObject.add("logRetention", context.serialize(src.getLogRetention()));
|
||||
for (Map.Entry<String, Object> entry : src.unknownFields.entrySet()) {
|
||||
jsonObject.add(entry.getKey(), context.serialize(entry.getValue()));
|
||||
}
|
||||
@@ -131,6 +147,7 @@ public final class GlobalConfig implements Cloneable, Observable {
|
||||
GlobalConfig config = new GlobalConfig();
|
||||
config.setAgreementVersion(Optional.ofNullable(obj.get("agreementVersion")).map(JsonElement::getAsInt).orElse(0));
|
||||
config.setPlatformPromptVersion(Optional.ofNullable(obj.get("platformPromptVersion")).map(JsonElement::getAsInt).orElse(0));
|
||||
config.setLogRetention(Optional.ofNullable(obj.get("logRetention")).map(JsonElement::getAsInt).orElse(20));
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
|
||||
if (!knownFields.contains(entry.getKey())) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.net.Proxy;
|
||||
import java.net.Proxy.Type;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class ProxyManager {
|
||||
private ProxyManager() {
|
||||
|
||||
@@ -23,23 +23,27 @@ import com.google.gson.stream.JsonWriter;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
@JsonAdapter(Theme.TypeAdapter.class)
|
||||
public class Theme {
|
||||
@@ -82,6 +86,30 @@ public class Theme {
|
||||
return cssCharset;
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private static Optional<Font> font;
|
||||
|
||||
private static Optional<Font> tryLoadFont() {
|
||||
//noinspection OptionalAssignedToNull
|
||||
if (font != null) {
|
||||
return font;
|
||||
}
|
||||
|
||||
Path path = Paths.get("font.ttf");
|
||||
if (!Files.isRegularFile(path)) {
|
||||
path = Paths.get("font.otf");
|
||||
}
|
||||
|
||||
if (Files.isRegularFile(path)) {
|
||||
try {
|
||||
return font = Optional.ofNullable(Font.loadFont(path.toAbsolutePath().toUri().toURL().toExternalForm(), 0));
|
||||
} catch (MalformedURLException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return font = Optional.empty();
|
||||
}
|
||||
|
||||
public static Theme getTheme() {
|
||||
Theme theme = config().getTheme();
|
||||
return theme == null ? BLUE : theme;
|
||||
@@ -121,9 +149,24 @@ public class Theme {
|
||||
String css = "/assets/css/blue.css";
|
||||
|
||||
String fontFamily = System.getProperty("hmcl.font.override", overrideFontFamily);
|
||||
String fontStyle = null;
|
||||
if (fontFamily == null) {
|
||||
Optional<Font> font = tryLoadFont();
|
||||
if (font.isPresent()) {
|
||||
fontFamily = font.get().getFamily();
|
||||
fontStyle = font.get().getStyle();
|
||||
}
|
||||
}
|
||||
|
||||
if (fontFamily != null || !this.color.equalsIgnoreCase(BLUE.color)) {
|
||||
Color textFill = getForegroundColor();
|
||||
String fontCss = "";
|
||||
if (fontFamily != null) {
|
||||
fontCss = "-fx-font-family: \"" + fontFamily + "\";";
|
||||
if (fontStyle != null && !fontStyle.isEmpty())
|
||||
fontCss += " -fx-font-style: \"" + fontStyle + "\";";
|
||||
}
|
||||
|
||||
try {
|
||||
File temp = File.createTempFile("hmcl", ".css");
|
||||
String themeText = IOUtils.readFullyAsString(Theme.class.getResourceAsStream("/assets/css/custom.css"))
|
||||
@@ -134,12 +177,12 @@ public class Theme {
|
||||
.replace("%base-rippler-color%", String.format("rgba(%d, %d, %d, 0.3)", (int) Math.ceil(paint.getRed() * 256), (int) Math.ceil(paint.getGreen() * 256), (int) Math.ceil(paint.getBlue() * 256)))
|
||||
.replace("%disabled-font-color%", String.format("rgba(%d, %d, %d, 0.7)", (int) Math.ceil(textFill.getRed() * 256), (int) Math.ceil(textFill.getGreen() * 256), (int) Math.ceil(textFill.getBlue() * 256)))
|
||||
.replace("%font-color%", getColorDisplayName(getForegroundColor()))
|
||||
.replace("%font%", Optional.ofNullable(fontFamily).map(f -> "-fx-font-family: \"" + f + "\";").orElse(""));
|
||||
.replace("%font%", fontCss);
|
||||
FileUtils.writeText(temp, themeText, getCssCharset());
|
||||
temp.deleteOnExit();
|
||||
css = temp.toURI().toString();
|
||||
} catch (IOException | NullPointerException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Unable to create theme stylesheet. Fallback to blue theme.", e);
|
||||
LOG.error("Unable to create theme stylesheet. Fallback to blue theme.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.*;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class Controllers {
|
||||
@@ -165,7 +166,7 @@ public final class Controllers {
|
||||
}
|
||||
|
||||
public static void initialize(Stage stage) {
|
||||
Logging.LOG.info("Start initializing application");
|
||||
LOG.info("Start initializing application");
|
||||
|
||||
Controllers.stage = stage;
|
||||
|
||||
@@ -298,7 +299,7 @@ public final class Controllers {
|
||||
});
|
||||
JFXButton noButton = new JFXButton(i18n("launcher.agreement.decline"));
|
||||
noButton.getStyleClass().add("dialog-cancel");
|
||||
noButton.setOnAction(e -> System.exit(1));
|
||||
noButton.setOnAction(e -> javafx.application.Platform.exit());
|
||||
agreementPane.setActions(agreementLink, yesButton, noButton);
|
||||
Controllers.dialog(agreementPane);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class CrashWindow extends Stage {
|
||||
FXUtils.setIcon(this);
|
||||
setTitle(i18n("message.error"));
|
||||
|
||||
setOnCloseRequest(e -> System.exit(1));
|
||||
setOnCloseRequest(e -> javafx.application.Platform.exit());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,7 +55,6 @@ import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.ResourceNotFoundError;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.javafx.ExtendedProperties;
|
||||
@@ -88,12 +87,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class FXUtils {
|
||||
@@ -110,7 +108,7 @@ public final class FXUtils {
|
||||
try {
|
||||
Files.deleteIfExists(entry.getValue());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, String.format("Failed to delete cache file %s.", entry.getValue()), e);
|
||||
LOG.warning(String.format("Failed to delete cache file %s.", entry.getValue()), e);
|
||||
}
|
||||
remoteImageCache.remove(entry.getKey());
|
||||
}
|
||||
@@ -337,7 +335,7 @@ public final class FXUtils {
|
||||
Tooltip.class.getMethod("setHideDelay", Duration.class).invoke(tooltip, new Duration(closeDelay));
|
||||
} catch (ReflectiveOperationException e2) {
|
||||
e.addSuppressed(e2);
|
||||
Logging.LOG.log(Level.SEVERE, "Cannot install tooltip", e);
|
||||
LOG.error("Cannot install tooltip", e);
|
||||
}
|
||||
Tooltip.install(node, tooltip);
|
||||
}
|
||||
@@ -370,7 +368,7 @@ public final class FXUtils {
|
||||
|
||||
public static void openFolder(File file) {
|
||||
if (!FileUtils.makeDirectory(file)) {
|
||||
LOG.log(Level.SEVERE, "Unable to make directory " + file);
|
||||
LOG.error("Unable to make directory " + file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -397,7 +395,7 @@ public final class FXUtils {
|
||||
else
|
||||
LOG.warning("Open " + path + " failed with code " + exitCode);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Unable to open " + path + " by executing " + openCommand, e);
|
||||
LOG.warning("Unable to open " + path + " by executing " + openCommand, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +403,7 @@ public final class FXUtils {
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().open(file);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.SEVERE, "Unable to open " + path + " by java.awt.Desktop.getDesktop()::open", e);
|
||||
LOG.error("Unable to open " + path + " by java.awt.Desktop.getDesktop()::open", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -432,7 +430,7 @@ public final class FXUtils {
|
||||
else
|
||||
LOG.warning("Show " + path + " in explorer failed with code " + exitCode);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Unable to show " + path + " in explorer", e);
|
||||
LOG.warning("Unable to show " + path + " in explorer", e);
|
||||
}
|
||||
|
||||
// Fallback to open folder
|
||||
@@ -469,7 +467,7 @@ public final class FXUtils {
|
||||
Runtime.getRuntime().exec(new String[]{"rundll32.exe", "url.dll,FileProtocolHandler", link});
|
||||
return;
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "An exception occurred while calling rundll32", e);
|
||||
LOG.warning("An exception occurred while calling rundll32", e);
|
||||
}
|
||||
}
|
||||
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD()) {
|
||||
@@ -481,7 +479,7 @@ public final class FXUtils {
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
Logging.LOG.log(Level.WARNING, "No known browser found");
|
||||
LOG.warning("No known browser found");
|
||||
}
|
||||
}
|
||||
try {
|
||||
@@ -491,9 +489,9 @@ public final class FXUtils {
|
||||
try {
|
||||
Runtime.getRuntime().exec(new String[]{"/usr/bin/open", link});
|
||||
} catch (IOException ex) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to open link: " + link, ex);
|
||||
LOG.warning("Unable to open link: " + link, ex);
|
||||
}
|
||||
Logging.LOG.log(Level.WARNING, "Failed to open link: " + link, e);
|
||||
LOG.warning("Failed to open link: " + link, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -509,7 +507,7 @@ public final class FXUtils {
|
||||
stage.setTitle(title);
|
||||
stage.showAndWait();
|
||||
} catch (NoClassDefFoundError | UnsatisfiedLinkError e) {
|
||||
LOG.log(Level.WARNING, "WebView is missing or initialization failed, use JEditorPane replaced", e);
|
||||
LOG.warning("WebView is missing or initialization failed, use JEditorPane replaced", e);
|
||||
|
||||
SwingUtils.initLookAndFeel();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
@@ -761,7 +759,7 @@ public final class FXUtils {
|
||||
try (InputStream inputStream = Files.newInputStream(currentPath)) {
|
||||
return new Image(inputStream, requestedWidth, requestedHeight, preserveRatio, smooth);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "An exception encountered while reading data from cached image file.", e);
|
||||
LOG.warning("An exception encountered while reading data from cached image file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,7 +769,7 @@ public final class FXUtils {
|
||||
try {
|
||||
Files.deleteIfExists(currentPath);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "An exception encountered while deleting broken cached image file.", e);
|
||||
LOG.warning("An exception encountered while deleting broken cached image file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -968,7 +966,7 @@ public final class FXUtils {
|
||||
}
|
||||
return texts;
|
||||
} catch (SAXException | ParserConfigurationException | IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse xml", e);
|
||||
LOG.warning("Failed to parse xml", e);
|
||||
return Collections.singletonList(new Text(segment));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
@@ -61,14 +61,13 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -132,7 +131,7 @@ public class GameCrashWindow extends Stage {
|
||||
try {
|
||||
crashReport = CrashReportAnalyzer.findCrashReport(rawLog);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read crash report", e);
|
||||
LOG.warning("Failed to read crash report", e);
|
||||
}
|
||||
if (crashReport == null) {
|
||||
crashReport = CrashReportAnalyzer.extractCrashReport(rawLog);
|
||||
@@ -149,7 +148,7 @@ public class GameCrashWindow extends Stage {
|
||||
try {
|
||||
log = FileUtils.readText(latestLog);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read logs/latest.log", e);
|
||||
LOG.warning("Failed to read logs/latest.log", e);
|
||||
return pair(new HashSet<CrashReportAnalyzer.Result>(), new HashSet<String>());
|
||||
}
|
||||
|
||||
@@ -158,7 +157,7 @@ public class GameCrashWindow extends Stage {
|
||||
loading.set(false);
|
||||
|
||||
if (exception != null) {
|
||||
LOG.log(Level.WARNING, "Failed to analyze crash report", exception);
|
||||
LOG.warning("Failed to analyze crash report", exception);
|
||||
reasonTextFlow.getChildren().setAll(FXUtils.parseSegment(i18n("game.crash.reason.unknown"), Controllers::onHyperlinkAction));
|
||||
} else {
|
||||
EnumMap<CrashReportAnalyzer.Rule, CrashReportAnalyzer.Result> results = new EnumMap<>(CrashReportAnalyzer.Rule.class);
|
||||
@@ -172,7 +171,7 @@ public class GameCrashWindow extends Stage {
|
||||
|
||||
List<Node> segments = new ArrayList<>(FXUtils.parseSegment(i18n("game.crash.feedback"), Controllers::onHyperlinkAction));
|
||||
|
||||
LOG.log(Level.INFO, "Number of reasons: " + results.size());
|
||||
LOG.info("Number of reasons: " + results.size());
|
||||
if (results.size() > 1) {
|
||||
segments.add(new Text("\n"));
|
||||
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason.multiple"), Controllers::onHyperlinkAction));
|
||||
@@ -204,7 +203,7 @@ public class GameCrashWindow extends Stage {
|
||||
case PERFORMANT_FOREST_OPTIFINE:
|
||||
case JADE_FOREST_OPTIFINE:
|
||||
message = i18n("game.crash.reason.mod", "OptiFine");
|
||||
LOG.log(Level.INFO, "Crash cause: " + result.getRule() + ": " + i18n("game.crash.reason.mod", "OptiFine"));
|
||||
LOG.info("Crash cause: " + result.getRule() + ": " + i18n("game.crash.reason.mod", "OptiFine"));
|
||||
break;
|
||||
default:
|
||||
message = i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
|
||||
@@ -212,17 +211,17 @@ public class GameCrashWindow extends Stage {
|
||||
.toArray());
|
||||
break;
|
||||
}
|
||||
LOG.log(Level.INFO, "Crash cause: " + result.getRule() + ": " + message);
|
||||
LOG.info("Crash cause: " + result.getRule() + ": " + message);
|
||||
segments.addAll(FXUtils.parseSegment(message, Controllers::onHyperlinkAction));
|
||||
segments.add(new Text("\n\n"));
|
||||
}
|
||||
if (results.isEmpty()) {
|
||||
if (!keywords.isEmpty()) {
|
||||
reasonTextFlow.getChildren().setAll(new Text(i18n("game.crash.reason.stacktrace", String.join(", ", keywords))));
|
||||
LOG.log(Level.INFO, "Crash reason unknown, but some log keywords have been found: " + String.join(", ", keywords));
|
||||
LOG.info("Crash reason unknown, but some log keywords have been found: " + String.join(", ", keywords));
|
||||
} else {
|
||||
reasonTextFlow.getChildren().setAll(FXUtils.parseSegment(i18n("game.crash.reason.unknown"), Controllers::onHyperlinkAction));
|
||||
LOG.log(Level.INFO, "Crash reason unknown");
|
||||
LOG.info("Crash reason unknown");
|
||||
}
|
||||
} else {
|
||||
feedbackTextFlow.setVisible(false);
|
||||
@@ -264,7 +263,7 @@ public class GameCrashWindow extends Stage {
|
||||
private void showLogWindow() {
|
||||
LogWindow logWindow = new LogWindow(managedProcess);
|
||||
|
||||
logWindow.logLine(Logging.filterForbiddenToken("Command: " + new CommandBuilder().addAll(managedProcess.getCommands())), Log4jLevel.INFO);
|
||||
logWindow.logLine(Logger.filterForbiddenToken("Command: " + new CommandBuilder().addAll(managedProcess.getCommands())), Log4jLevel.INFO);
|
||||
if (managedProcess.getClasspath() != null)
|
||||
logWindow.logLine("ClassPath: " + managedProcess.getClasspath(), Log4jLevel.INFO);
|
||||
for (Map.Entry<String, Log4jLevel> entry : logs)
|
||||
@@ -287,7 +286,7 @@ public class GameCrashWindow extends Stage {
|
||||
FXUtils.showFileInExplorer(logFile);
|
||||
alert = new Alert(Alert.AlertType.INFORMATION, i18n("settings.launcher.launcher_log.export.success", logFile));
|
||||
} else {
|
||||
LOG.log(Level.WARNING, "Failed to export game crash info", exception);
|
||||
LOG.warning("Failed to export game crash info", exception);
|
||||
alert = new Alert(Alert.AlertType.WARNING, i18n("settings.launcher.launcher_log.export.failed") + "\n" + StringUtils.getStackTrace(exception));
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,12 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.StringUtils.parseEscapeSequence;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -210,7 +209,7 @@ public final class LogWindow extends Stage {
|
||||
try {
|
||||
Files.write(logFile, logs.stream().map(x -> x.log).collect(Collectors.toList()));
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to export logs", e);
|
||||
LOG.warning("Failed to export logs", e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,7 +237,7 @@ public final class LogWindow extends Stage {
|
||||
FXUtils.showFileInExplorer(dumpFile);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Failed to create minecraft jstack dump", e);
|
||||
LOG.warning("Failed to create minecraft jstack dump", e);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, i18n("logwindow.export_dump.dependency_ok.button"));
|
||||
|
||||
@@ -27,11 +27,10 @@ import org.jackhuang.hmcl.Metadata;
|
||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||
import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.Metadata.CHANGELOG_URL;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class UpgradeDialog extends JFXDialogLayout {
|
||||
@@ -56,7 +55,7 @@ public class UpgradeDialog extends JFXDialogLayout {
|
||||
});
|
||||
setBody(webView);
|
||||
} catch (NoClassDefFoundError | UnsatisfiedLinkError e) {
|
||||
LOG.log(Level.WARNING, "WebView is missing or initialization failed", e);
|
||||
LOG.warning("WebView is missing or initialization failed", e);
|
||||
FXUtils.openLink(url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import javafx.scene.control.Tooltip;
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.TextureModel;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.game.TexturesLoader;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
@@ -58,7 +57,7 @@ public class AccountAdvancedListItem extends AdvancedListItem {
|
||||
tooltip.setText(i18n("account.create"));
|
||||
|
||||
TexturesLoader.unbindAvatar(canvas);
|
||||
TexturesLoader.drawAvatar(canvas, TexturesLoader.getDefaultSkin(TextureModel.STEVE).getImage());
|
||||
TexturesLoader.drawAvatar(canvas, TexturesLoader.getDefaultSkinImage());
|
||||
|
||||
} else {
|
||||
titleProperty().bind(BindingMapping.of(account, Account::getCharacter));
|
||||
|
||||
@@ -54,11 +54,10 @@ import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.util.Collections.emptySet;
|
||||
import static javafx.beans.binding.Bindings.createBooleanBinding;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class AccountListItem extends RadioButton {
|
||||
@@ -109,11 +108,11 @@ public class AccountListItem extends RadioButton {
|
||||
} catch (CancellationException e1) {
|
||||
// ignore cancellation
|
||||
} catch (Exception e1) {
|
||||
LOG.log(Level.WARNING, "Failed to refresh " + account + " with password", e1);
|
||||
LOG.warning("Failed to refresh " + account + " with password", e1);
|
||||
throw e1;
|
||||
}
|
||||
} catch (AuthenticationException e) {
|
||||
LOG.log(Level.WARNING, "Failed to refresh " + account + " with token", e);
|
||||
LOG.warning("Failed to refresh " + account + " with token", e);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,10 +44,9 @@ import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor;
|
||||
|
||||
@@ -137,7 +136,7 @@ public class AccountListPage extends DecoratorAnimatedPage implements DecoratorP
|
||||
try {
|
||||
host = URI.create(server.getUrl()).getHost();
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.log(Level.WARNING, "Unparsable authlib-injector server url " + server.getUrl(), e);
|
||||
LOG.warning("Unparsable authlib-injector server url " + server.getUrl(), e);
|
||||
}
|
||||
item.subtitleProperty().set(host);
|
||||
Tooltip tooltip = new Tooltip();
|
||||
|
||||
@@ -35,11 +35,10 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class AddAuthlibInjectorServerPane extends TransitionPane implements DialogAware {
|
||||
@@ -201,7 +200,7 @@ public final class AddAuthlibInjectorServerPane extends TransitionPane implement
|
||||
|
||||
this.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT.getAnimationProducer());
|
||||
} else {
|
||||
LOG.log(Level.WARNING, "Failed to resolve auth server: " + url, exception);
|
||||
LOG.warning("Failed to resolve auth server: " + url, exception);
|
||||
lblCreationWarning.setText(resolveFetchExceptionMessage(exception));
|
||||
}
|
||||
}).start();
|
||||
|
||||
@@ -36,10 +36,9 @@ import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class ClassicAccountLoginDialog extends StackPane {
|
||||
@@ -109,7 +108,7 @@ public class ClassicAccountLoginDialog extends StackPane {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
progressBar.setVisible(false);
|
||||
}, e -> {
|
||||
LOG.log(Level.INFO, "Failed to login with password: " + oldAccount, e);
|
||||
LOG.info("Failed to login with password: " + oldAccount, e);
|
||||
if (e instanceof NoSelectedCharacterException) {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
} else {
|
||||
|
||||
@@ -21,9 +21,8 @@ import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class OAuthAccountLoginDialog extends DialogPane {
|
||||
@@ -96,7 +95,7 @@ public class OAuthAccountLoginDialog extends DialogPane {
|
||||
success.accept(authInfo);
|
||||
onSuccess();
|
||||
} else {
|
||||
LOG.log(Level.INFO, "Failed to login when credentials expired: " + account, exception);
|
||||
LOG.info("Failed to login when credentials expired: " + account, exception);
|
||||
onFailure(Accounts.localizeErrorMessage(exception));
|
||||
}
|
||||
}).start();
|
||||
|
||||
@@ -25,7 +25,6 @@ import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.*;
|
||||
@@ -35,6 +34,7 @@ import moe.mickey.minecraft.skin.fx.animation.SkinAniWavingArms;
|
||||
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
|
||||
import org.jackhuang.hmcl.auth.offline.Skin;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.TextureModel;
|
||||
import org.jackhuang.hmcl.game.TexturesLoader;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
@@ -42,11 +42,11 @@ import org.jackhuang.hmcl.ui.construct.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class OfflineAccountSkinPane extends StackPane {
|
||||
@@ -71,7 +71,7 @@ public class OfflineAccountSkinPane extends StackPane {
|
||||
|
||||
BorderPane pane = new BorderPane();
|
||||
|
||||
SkinCanvas canvas = new SkinCanvas(SkinCanvas.STEVE, 300, 300, true);
|
||||
SkinCanvas canvas = new SkinCanvas(TexturesLoader.getDefaultSkinImage(), 300, 300, true);
|
||||
StackPane canvasPane = new StackPane(canvas);
|
||||
canvasPane.setPrefWidth(300);
|
||||
canvasPane.setPrefHeight(300);
|
||||
@@ -116,11 +116,11 @@ public class OfflineAccountSkinPane extends StackPane {
|
||||
));
|
||||
|
||||
modelCombobox.setConverter(stringConverter(model -> i18n("account.skin.model." + model.modelName)));
|
||||
modelCombobox.getItems().setAll(TextureModel.STEVE, TextureModel.ALEX);
|
||||
modelCombobox.getItems().setAll(TextureModel.WIDE, TextureModel.SLIM);
|
||||
|
||||
if (account.getSkin() == null) {
|
||||
skinItem.setSelectedData(Skin.Type.DEFAULT);
|
||||
modelCombobox.setValue(TextureModel.STEVE);
|
||||
modelCombobox.setValue(TextureModel.WIDE);
|
||||
} else {
|
||||
skinItem.setSelectedData(account.getSkin().getType());
|
||||
cslApiField.setText(account.getSkin().getCslApi());
|
||||
@@ -133,16 +133,21 @@ public class OfflineAccountSkinPane extends StackPane {
|
||||
getSkin().load(account.getUsername())
|
||||
.whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
if (exception != null) {
|
||||
LOG.log(Level.WARNING, "Failed to load skin", exception);
|
||||
LOG.warning("Failed to load skin", exception);
|
||||
Controllers.showToast(i18n("message.failed"));
|
||||
} else {
|
||||
UUID uuid = this.account.getUUID();
|
||||
if (result == null || result.getSkin() == null && result.getCape() == null) {
|
||||
canvas.updateSkin(getDefaultTexture(), isDefaultSlim(), null);
|
||||
canvas.updateSkin(
|
||||
TexturesLoader.getDefaultSkin(uuid).getImage(),
|
||||
TexturesLoader.getDefaultModel(uuid) == TextureModel.SLIM,
|
||||
null
|
||||
);
|
||||
return;
|
||||
}
|
||||
canvas.updateSkin(
|
||||
result.getSkin() != null ? result.getSkin().getImage() : getDefaultTexture(),
|
||||
result.getModel() == TextureModel.ALEX,
|
||||
result.getSkin() != null ? result.getSkin().getImage() : TexturesLoader.getDefaultSkin(uuid).getImage(),
|
||||
result.getModel() == TextureModel.SLIM,
|
||||
result.getCape() != null ? result.getCape().getImage() : null);
|
||||
}
|
||||
}).start();
|
||||
@@ -198,17 +203,4 @@ public class OfflineAccountSkinPane extends StackPane {
|
||||
private Skin getSkin() {
|
||||
return new Skin(skinItem.getSelectedData(), cslApiField.getText(), modelCombobox.getValue(), skinSelector.getValue(), capeSelector.getValue());
|
||||
}
|
||||
|
||||
private boolean isDefaultSlim() {
|
||||
return TextureModel.detectUUID(account.getUUID()) == TextureModel.ALEX;
|
||||
}
|
||||
|
||||
private Image getDefaultTexture() {
|
||||
if (isDefaultSlim()) {
|
||||
return SkinCanvas.ALEX;
|
||||
} else {
|
||||
return SkinCanvas.STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,11 +31,11 @@ import org.jackhuang.hmcl.ui.animation.AnimationProducer;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
||||
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class Navigator extends TransitionPane {
|
||||
private static final String PROPERTY_DIALOG_CLOSE_HANDLER = Navigator.class.getName() + ".closeListener";
|
||||
@@ -65,7 +65,7 @@ public class Navigator extends TransitionPane {
|
||||
if (from == node)
|
||||
return;
|
||||
|
||||
Logging.LOG.info("Navigate to " + node);
|
||||
LOG.info("Navigate to " + node);
|
||||
|
||||
stack.push(node);
|
||||
backable.set(canGoBack());
|
||||
@@ -104,11 +104,11 @@ public class Navigator extends TransitionPane {
|
||||
|
||||
if (stack.peek() != from) {
|
||||
// Allow page to be closed multiple times.
|
||||
Logging.LOG.log(Level.INFO, "Closing already closed page: " + from, new Throwable());
|
||||
LOG.info("Closing already closed page: " + from, new Throwable());
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.LOG.info("Closed page " + from);
|
||||
LOG.info("Closed page " + from);
|
||||
|
||||
Node poppedNode = stack.pop();
|
||||
NavigationEvent exited = new NavigationEvent(this, poppedNode, Navigation.NavigationDirection.PREVIOUS, NavigationEvent.EXITED);
|
||||
|
||||
@@ -19,11 +19,12 @@ package org.jackhuang.hmcl.ui.construct;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Stack;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class StackContainerPane extends StackPane {
|
||||
private final Stack<Node> stack = new Stack<>();
|
||||
|
||||
@@ -39,7 +40,7 @@ public class StackContainerPane extends StackPane {
|
||||
stack.push(node);
|
||||
getChildren().setAll(node);
|
||||
|
||||
Logging.LOG.info(this + " " + stack);
|
||||
LOG.info(this + " " + stack);
|
||||
}
|
||||
|
||||
public void pop(Node node) {
|
||||
@@ -49,7 +50,7 @@ public class StackContainerPane extends StackPane {
|
||||
else
|
||||
getChildren().setAll(stack.peek());
|
||||
|
||||
Logging.LOG.info(this + " " + stack + ", removed: " + flag + ", object: " + node);
|
||||
LOG.info(this + " " + stack + ", removed: " + flag + ", object: " + node);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
||||
@@ -50,6 +50,10 @@ import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -58,15 +62,13 @@ import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.newBuiltinImage;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.io.FileUtils.getExtension;
|
||||
|
||||
public class DecoratorController {
|
||||
@@ -168,8 +170,23 @@ public class DecoratorController {
|
||||
break;
|
||||
case NETWORK:
|
||||
String backgroundImageUrl = config().getBackgroundImageUrl();
|
||||
if (backgroundImageUrl != null && NetworkUtils.isURL(backgroundImageUrl))
|
||||
image = tryLoadImage(backgroundImageUrl).orElse(null);
|
||||
if (backgroundImageUrl != null) {
|
||||
try {
|
||||
URLConnection connection = NetworkUtils.createConnection(new URL(backgroundImageUrl));
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
connection = NetworkUtils.resolveConnection((HttpURLConnection) connection);
|
||||
}
|
||||
|
||||
try (InputStream input = connection.getInputStream()) {
|
||||
image = new Image(input);
|
||||
if (image.isError()) {
|
||||
throw image.getException();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warning("Couldn't load background image", e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLASSIC:
|
||||
image = newBuiltinImage("/assets/img/background-classic.jpg");
|
||||
@@ -215,7 +232,7 @@ public class DecoratorController {
|
||||
})
|
||||
.collect(toList());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to list files in ./bg", e);
|
||||
LOG.warning("Failed to list files in ./bg", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -244,12 +261,12 @@ public class DecoratorController {
|
||||
try {
|
||||
img = new Image(url);
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.log(WARNING, "Couldn't load background image", e);
|
||||
LOG.warning("Couldn't load background image", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (img.getException() != null) {
|
||||
LOG.log(WARNING, "Couldn't load background image", img.getException());
|
||||
LOG.warning("Couldn't load background image", img.getException());
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,9 @@ import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class LocalModpackPage extends ModpackPage {
|
||||
@@ -121,7 +120,7 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
|
||||
controller.getSettings().put(MODPACK_MANUALLY_CREATED, true);
|
||||
} else if (exception != null) {
|
||||
LOG.log(Level.WARNING, "Failed to read modpack manifest", exception);
|
||||
LOG.warning("Failed to read modpack manifest", exception);
|
||||
Controllers.dialog(i18n("modpack.task.install.error"), i18n("message.error"), MessageDialogPane.MessageType.ERROR);
|
||||
Platform.runLater(controller::onEnd);
|
||||
} else {
|
||||
|
||||
@@ -57,11 +57,10 @@ import org.jackhuang.hmcl.util.Holder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.wrap;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.formatDateTime;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -232,7 +231,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
}
|
||||
});
|
||||
} else {
|
||||
LOG.log(Level.WARNING, "Failed to fetch versions list", exception);
|
||||
LOG.warning("Failed to fetch versions list", exception);
|
||||
Platform.runLater(() -> {
|
||||
if (versionList != currentVersionList) return;
|
||||
root.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
|
||||
|
||||
@@ -179,7 +179,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_SERVER) {
|
||||
Hyperlink hyperlink = new Hyperlink(i18n("modpack.wizard.step.initialization.server"));
|
||||
hyperlink.setOnMouseClicked(e -> {
|
||||
FXUtils.openLink("https://docs.hmcl.net/modpack/serverpack.htm");
|
||||
FXUtils.openLink("https://docs.hmcl.net/modpack/serverpack.html");
|
||||
});
|
||||
borderPane.setTop(hyperlink);
|
||||
} else {
|
||||
|
||||
@@ -54,12 +54,11 @@ import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||
@@ -102,7 +101,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||
try {
|
||||
Controllers.navigate(new NBTEditorPage(file));
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Fail to open nbt file", e);
|
||||
LOG.warning("Fail to open nbt file", e);
|
||||
Controllers.dialog(i18n("nbt.open.failed") + "\n\n" + StringUtils.getStackTrace(e),
|
||||
i18n("message.error"), MessageDialogPane.MessageType.ERROR);
|
||||
}
|
||||
|
||||
@@ -31,24 +31,23 @@ import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
||||
import org.jackhuang.hmcl.upgrade.UpdateChannel;
|
||||
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
||||
import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.Locales;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
|
||||
|
||||
@@ -130,11 +129,11 @@ public final class SettingsPage extends SettingsView {
|
||||
Path logFile = Paths.get("hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".log").toAbsolutePath();
|
||||
|
||||
LOG.info("Exporting logs to " + logFile);
|
||||
try {
|
||||
Files.write(logFile, Logging.getRawLogs());
|
||||
try (OutputStream output = Files.newOutputStream(logFile)) {
|
||||
LOG.exportLogs(output);
|
||||
} catch (IOException e) {
|
||||
Platform.runLater(() -> Controllers.dialog(i18n("settings.launcher.launcher_log.export.failed") + "\n" + StringUtils.getStackTrace(e), null, MessageType.ERROR));
|
||||
LOG.log(Level.WARNING, "Failed to export logs", e);
|
||||
LOG.warning("Failed to export logs", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ public abstract class SettingsView extends StackPane {
|
||||
languagePane.setLeft(left);
|
||||
|
||||
cboLanguage = new JFXComboBox<>();
|
||||
cboLanguage.setConverter(stringConverter(locale -> locale.getName(I18n.getCurrentLocale().getResourceBundle())));
|
||||
cboLanguage.setConverter(stringConverter(I18n::getName));
|
||||
FXUtils.setLimitWidth(cboLanguage, 300);
|
||||
languagePane.setRight(cboLanguage);
|
||||
|
||||
|
||||
@@ -18,10 +18,9 @@ import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class NBTEditorPage extends BorderPane implements DecoratorPage {
|
||||
@@ -53,7 +52,7 @@ public class NBTEditorPage extends BorderPane implements DecoratorPage {
|
||||
try {
|
||||
save();
|
||||
} catch (IOException ex) {
|
||||
LOG.log(Level.WARNING, "Failed to save NBT file", ex);
|
||||
LOG.warning("Failed to save NBT file", ex);
|
||||
Controllers.dialog(i18n("nbt.save.failed") + "\n\n" + StringUtils.getStackTrace(ex));
|
||||
}
|
||||
});
|
||||
@@ -73,7 +72,7 @@ public class NBTEditorPage extends BorderPane implements DecoratorPage {
|
||||
}, Schedulers.javafx())
|
||||
.handleAsync((result, e) -> {
|
||||
if (e != null) {
|
||||
LOG.log(Level.WARNING, "Fail to open nbt file", e);
|
||||
LOG.warning("Fail to open nbt file", e);
|
||||
Controllers.dialog(i18n("nbt.open.failed") + "\n\n" + StringUtils.getStackTrace(e), null, MessageDialogPane.MessageType.WARNING, cancelButton::fire);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.ListPageBase;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||
|
||||
@@ -38,8 +37,8 @@ import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class DatapackListPage extends ListPageBase<DatapackListPageSkin.DatapackInfoObject> implements DecoratorPage {
|
||||
@@ -71,7 +70,7 @@ public class DatapackListPage extends ListPageBase<DatapackListPageSkin.Datapack
|
||||
zip.loadFromZip();
|
||||
zip.installTo(worldDir);
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + datapack, e);
|
||||
LOG.warning("Unable to parse datapack file " + datapack, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +116,7 @@ public class DatapackListPage extends ListPageBase<DatapackListPageSkin.Datapack
|
||||
datapack.deletePack(pack);
|
||||
} catch (IOException e) {
|
||||
// Fail to remove mods if the game is running or the datapack is absent.
|
||||
Logging.LOG.warning("Failed to delete datapack " + pack);
|
||||
LOG.warning("Failed to delete datapack " + pack);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
protected void updateControl(RemoteMod dataItem, boolean empty) {
|
||||
if (empty) return;
|
||||
ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(getSkinnable().repository.getType()).getModByCurseForgeId(dataItem.getSlug());
|
||||
content.setTitle(mod != null && I18n.getCurrentLocale().getLocale() == Locale.CHINA ? mod.getDisplayName() : dataItem.getTitle());
|
||||
content.setTitle(mod != null && I18n.isUseChinese() ? mod.getDisplayName() : dataItem.getTitle());
|
||||
content.setSubtitle(dataItem.getDescription());
|
||||
content.getTags().setAll(dataItem.getCategories().stream()
|
||||
.map(category -> getSkinnable().getLocalizedCategory(category))
|
||||
|
||||
@@ -240,7 +240,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
TwoLineListItem content = new TwoLineListItem();
|
||||
HBox.setHgrow(content, Priority.ALWAYS);
|
||||
ModTranslations.Mod mod = getSkinnable().translations.getModByCurseForgeId(getSkinnable().addon.getSlug());
|
||||
content.setTitle(mod != null && I18n.getCurrentLocale().getLocale() == Locale.CHINA ? mod.getDisplayName() : getSkinnable().addon.getTitle());
|
||||
content.setTitle(mod != null && I18n.isUseChinese() ? mod.getDisplayName() : getSkinnable().addon.getTitle());
|
||||
content.setSubtitle(getSkinnable().addon.getDescription());
|
||||
content.getTags().setAll(getSkinnable().addon.getCategories().stream()
|
||||
.map(category -> getSkinnable().page.getLocalizedCategory(category))
|
||||
@@ -253,14 +253,6 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
descriptionPane.getChildren().add(openMcmodButton);
|
||||
openMcmodButton.setMinWidth(Region.USE_PREF_SIZE);
|
||||
runInFX(() -> FXUtils.installFastTooltip(openMcmodButton, i18n("mods.mcmod")));
|
||||
|
||||
// if (StringUtils.isNotBlank(getSkinnable().mod.getMcbbs())) {
|
||||
// JFXHyperlink openMcbbsButton = new JFXHyperlink(i18n("mods.mcbbs"));
|
||||
// openMcbbsButton.setExternalLink(ModManager.getMcbbsUrl(getSkinnable().mod.getMcbbs()));
|
||||
// descriptionPane.getChildren().add(openMcbbsButton);
|
||||
// openMcbbsButton.setMinWidth(Region.USE_PREF_SIZE);
|
||||
// runInFX(() -> FXUtils.installFastTooltip(openMcbbsButton, i18n("mods.mcbbs")));
|
||||
// }
|
||||
}
|
||||
|
||||
JFXHyperlink openUrlButton = new JFXHyperlink(control.page.getLocalizedOfficialPage());
|
||||
@@ -352,15 +344,21 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
container.setOnMouseClicked(e -> Controllers.navigate(new DownloadPage(page, addon, version, callback)));
|
||||
getChildren().setAll(container);
|
||||
|
||||
ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(page.repository.getType()).getModByCurseForgeId(addon.getSlug());
|
||||
content.setTitle(mod != null && I18n.getCurrentLocale().getLocale() == Locale.CHINA ? mod.getDisplayName() : addon.getTitle());
|
||||
content.setSubtitle(addon.getDescription());
|
||||
content.getTags().setAll(addon.getCategories().stream()
|
||||
.map(page::getLocalizedCategory)
|
||||
.collect(Collectors.toList()));
|
||||
if (addon != RemoteMod.BROKEN) {
|
||||
ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(page.repository.getType()).getModByCurseForgeId(addon.getSlug());
|
||||
content.setTitle(mod != null && I18n.isUseChinese() ? mod.getDisplayName() : addon.getTitle());
|
||||
content.setSubtitle(addon.getDescription());
|
||||
content.getTags().setAll(addon.getCategories().stream()
|
||||
.map(page::getLocalizedCategory)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
if (StringUtils.isNotBlank(addon.getIconUrl())) {
|
||||
imageView.setImage(FXUtils.newRemoteImage(addon.getIconUrl(), 40, 40, true, true, true));
|
||||
if (StringUtils.isNotBlank(addon.getIconUrl())) {
|
||||
imageView.setImage(FXUtils.newRemoteImage(addon.getIconUrl(), 40, 40, true, true, true));
|
||||
}
|
||||
} else {
|
||||
content.setTitle(i18n("mods.broken_dependency.title"));
|
||||
content.setSubtitle(i18n("mods.broken_dependency.desc"));
|
||||
imageView.setImage(FXUtils.newBuiltinImage("/assets/img/icon@8x.png", 40, 40, true, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,11 @@ import java.io.IOException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT;
|
||||
import static org.jackhuang.hmcl.util.Lang.handleUncaught;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class GameItem extends Control {
|
||||
@@ -84,7 +83,7 @@ public class GameItem extends Control {
|
||||
if (config == null) return;
|
||||
tag.set(config.getVersion());
|
||||
} catch (IOException | JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read modpack configuration from " + version, e);
|
||||
LOG.warning("Failed to read modpack configuration from " + version, e);
|
||||
}
|
||||
}, Platform::runLater)
|
||||
.exceptionally(handleUncaught);
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.ListPageBase;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.PageAware;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
@@ -45,10 +44,10 @@ import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObject> implements VersionPage.VersionLoadable, PageAware {
|
||||
@@ -65,7 +64,7 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
|
||||
try {
|
||||
modManager.addMod(it.toPath());
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to parse mod file " + it, e);
|
||||
LOG.warning("Unable to parse mod file " + it, e);
|
||||
}
|
||||
});
|
||||
loadMods(modManager);
|
||||
@@ -135,7 +134,7 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
|
||||
modManager.addMod(file.toPath());
|
||||
succeeded.add(file.getName());
|
||||
} catch (Exception e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to add mod " + file, e);
|
||||
LOG.warning("Unable to add mod " + file, e);
|
||||
failed.add(file.getName());
|
||||
|
||||
// Actually addMod will not throw exceptions because FileChooser has already filtered files.
|
||||
|
||||
@@ -61,14 +61,13 @@ import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton2;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.StringUtils.isNotBlank;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@@ -218,7 +217,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
Pattern pattern = Pattern.compile(queryString.substring("regex:".length()));
|
||||
predicate = s -> pattern.matcher(s).find();
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Illegal regular expression", e);
|
||||
LOG.warning("Illegal regular expression", e);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -391,15 +390,6 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
getActions().add(officialPageButton);
|
||||
}
|
||||
|
||||
// if (modInfo.getMod() != null && StringUtils.isNotBlank(modInfo.getMod().getMcbbs())) {
|
||||
// JFXHyperlink mcbbsButton = new JFXHyperlink(i18n("mods.mcbbs"));
|
||||
// mcbbsButton.setOnAction(e -> {
|
||||
// fireEvent(new DialogCloseEvent());
|
||||
// FXUtils.openLink(ModManager.getMcbbsUrl(modInfo.getMod().getMcbbs()));
|
||||
// });
|
||||
// getActions().add(mcbbsButton);
|
||||
// }
|
||||
|
||||
if (modInfo.getMod() == null || StringUtils.isBlank(modInfo.getMod().getMcmod())) {
|
||||
JFXHyperlink searchButton = new JFXHyperlink(i18n("mods.mcmod.search"));
|
||||
searchButton.setOnAction(e -> {
|
||||
@@ -490,10 +480,8 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
content.getTags().add(i18n("install.installer.quilt"));
|
||||
break;
|
||||
}
|
||||
if (dataItem.getMod() != null) {
|
||||
if (I18n.getCurrentLocale().getLocale() == Locale.CHINA) {
|
||||
content.getTags().add(dataItem.getMod().getDisplayName());
|
||||
}
|
||||
if (dataItem.getMod() != null && I18n.isUseChinese()) {
|
||||
content.getTags().add(dataItem.getMod().getDisplayName());
|
||||
}
|
||||
content.setSubtitle(dataItem.getSubtitle());
|
||||
if (booleanProperty != null) {
|
||||
|
||||
@@ -24,10 +24,9 @@ import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
/**
|
||||
@@ -127,7 +126,7 @@ public enum ModTranslations {
|
||||
mods = Arrays.stream(modData.split("\n")).filter(line -> !line.startsWith("#")).map(Mod::new).collect(Collectors.toList());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.WARNING, "Failed to load " + resourceName, e);
|
||||
LOG.warning("Failed to load " + resourceName, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -198,10 +197,9 @@ public enum ModTranslations {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class Mod {
|
||||
public static final class Mod {
|
||||
private final String curseforge;
|
||||
private final String mcmod;
|
||||
private final String mcbbs;
|
||||
private final List<String> modIds;
|
||||
private final String name;
|
||||
private final String subname;
|
||||
@@ -209,23 +207,21 @@ public enum ModTranslations {
|
||||
|
||||
public Mod(String line) {
|
||||
String[] items = line.split(";", -1);
|
||||
if (items.length != 7) {
|
||||
throw new IllegalArgumentException("Illegal mod data line, 7 items expected " + line);
|
||||
if (items.length != 6) {
|
||||
throw new IllegalArgumentException("Illegal mod data line, 6 items expected " + line);
|
||||
}
|
||||
|
||||
curseforge = items[0];
|
||||
mcmod = items[1];
|
||||
mcbbs = items[2];
|
||||
modIds = Collections.unmodifiableList(Arrays.asList(items[3].split(",")));
|
||||
name = items[4];
|
||||
subname = items[5];
|
||||
abbr = items[6];
|
||||
modIds = Collections.unmodifiableList(Arrays.asList(items[2].split(",")));
|
||||
name = items[3];
|
||||
subname = items[4];
|
||||
abbr = items[5];
|
||||
}
|
||||
|
||||
public Mod(String curseforge, String mcmod, String mcbbs, List<String> modIds, String name, String subname, String abbr) {
|
||||
public Mod(String curseforge, String mcmod, List<String> modIds, String name, String subname, String abbr) {
|
||||
this.curseforge = curseforge;
|
||||
this.mcmod = mcmod;
|
||||
this.mcbbs = mcbbs;
|
||||
this.modIds = modIds;
|
||||
this.name = name;
|
||||
this.subname = subname;
|
||||
@@ -252,10 +248,6 @@ public enum ModTranslations {
|
||||
return mcmod;
|
||||
}
|
||||
|
||||
public String getMcbbs() {
|
||||
return mcbbs;
|
||||
}
|
||||
|
||||
public List<String> getModIds() {
|
||||
return modIds;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,11 @@ import org.jackhuang.hmcl.game.LocalizedRemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class ResourcePackDownloadListPage extends DownloadListPage {
|
||||
@@ -66,10 +70,18 @@ public class ResourcePackDownloadListPage extends DownloadListPage {
|
||||
|
||||
@Override
|
||||
protected String getLocalizedCategory(String category) {
|
||||
String key;
|
||||
if ("mods.modrinth".equals(downloadSource.get())) {
|
||||
return i18n("modrinth.category." + category);
|
||||
key = "modrinth.category." + category;
|
||||
} else {
|
||||
return i18n("curse.category." + category);
|
||||
key = "curse.category." + category;
|
||||
}
|
||||
|
||||
try {
|
||||
return I18n.getResourceBundle().getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
LOG.warning("Cannot find key " + key + " in resource bundle", e);
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,13 +31,11 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.SVG;
|
||||
import org.jackhuang.hmcl.ui.construct.DialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class VersionIconDialog extends DialogPane {
|
||||
@@ -74,20 +72,19 @@ public class VersionIconDialog extends DialogPane {
|
||||
|
||||
private void exploreIcon() {
|
||||
FileChooser chooser = new FileChooser();
|
||||
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(i18n("extension.png"), "*.png"));
|
||||
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(i18n("extension.png"), "*.png", "*.jpg", "*.bmp", "*.gif"));
|
||||
File selectedFile = chooser.showOpenDialog(Controllers.getStage());
|
||||
if (selectedFile != null) {
|
||||
File iconFile = profile.getRepository().getVersionIconFile(versionId);
|
||||
try {
|
||||
FileUtils.copyFile(selectedFile, iconFile);
|
||||
profile.getRepository().setVersionIconFile(versionId, selectedFile);
|
||||
|
||||
if (vs != null) {
|
||||
vs.setVersionIcon(VersionIconType.DEFAULT);
|
||||
}
|
||||
|
||||
onAccept();
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Failed to copy icon file from " + selectedFile + " to " + iconFile, e);
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
LOG.error("Failed to set icon file: " + selectedFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,9 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
|
||||
}
|
||||
|
||||
private void clearAssets() {
|
||||
FileUtils.deleteDirectoryQuietly(new File(getProfile().getRepository().getBaseDirectory(), "assets"));
|
||||
File baseDirectory = getProfile().getRepository().getBaseDirectory();
|
||||
FileUtils.deleteDirectoryQuietly(new File(baseDirectory, "assets"));
|
||||
FileUtils.deleteDirectoryQuietly(new File(baseDirectory, "resources"));
|
||||
}
|
||||
|
||||
private void clearJunkFiles() {
|
||||
|
||||
@@ -48,7 +48,6 @@ import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
@@ -642,9 +641,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
if (versionId == null)
|
||||
return;
|
||||
|
||||
File iconFile = profile.getRepository().getVersionIconFile(versionId);
|
||||
if (iconFile.exists())
|
||||
iconFile.delete();
|
||||
profile.getRepository().deleteIconFile(versionId);
|
||||
VersionSetting localVersionSetting = profile.getRepository().getLocalVersionSettingOrCreate(versionId);
|
||||
if (localVersionSetting != null) {
|
||||
localVersionSetting.setVersionIcon(VersionIconType.DEFAULT);
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.jackhuang.hmcl.ui.construct.PromptDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||
import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider;
|
||||
import org.jackhuang.hmcl.ui.export.ExportWizardProvider;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
@@ -55,8 +54,8 @@ import java.nio.file.Path;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class Versions {
|
||||
@@ -184,7 +183,7 @@ public final class Versions {
|
||||
try {
|
||||
profile.getRepository().clean(id);
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to clean game directory", e);
|
||||
LOG.warning("Unable to clean game directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,8 @@ import java.text.DecimalFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.formatDateTime;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -421,7 +420,7 @@ public final class WorldInfoPage extends StackPane implements DecoratorPage {
|
||||
try {
|
||||
this.world.writeLevelDat(levelDat);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to save level.dat of world " + world.getWorldName(), e);
|
||||
LOG.warning("Failed to save level.dat of world " + world.getWorldName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.*;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -39,10 +38,10 @@ import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class WorldListPage extends ListPageBase<WorldListItem> implements VersionPage.VersionLoadable {
|
||||
@@ -139,7 +138,7 @@ public class WorldListPage extends ListPageBase<WorldListItem> implements Versio
|
||||
}).start();
|
||||
}, world.getWorldName());
|
||||
}, e -> {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e);
|
||||
LOG.warning("Unable to parse world file " + zipFile, e);
|
||||
Controllers.dialog(i18n("world.import.invalid"));
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@ package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class WizardController implements Navigation {
|
||||
private final WizardDisplayer displayer;
|
||||
private WizardProvider provider = null;
|
||||
@@ -71,7 +72,7 @@ public class WizardController implements Navigation {
|
||||
|
||||
displayer.onStart();
|
||||
|
||||
Logging.LOG.info("Navigating to " + page + ", pages: " + pages);
|
||||
LOG.info("Navigating to " + page + ", pages: " + pages);
|
||||
displayer.navigateTo(page, NavigationDirection.START);
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ public class WizardController implements Navigation {
|
||||
if (page instanceof WizardPage)
|
||||
((WizardPage) page).onNavigate(settings);
|
||||
|
||||
Logging.LOG.info("Navigating to " + page + ", pages: " + pages);
|
||||
LOG.info("Navigating to " + page + ", pages: " + pages);
|
||||
displayer.navigateTo(page, NavigationDirection.NEXT);
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ public class WizardController implements Navigation {
|
||||
if (prevPage instanceof WizardPage)
|
||||
((WizardPage) prevPage).onNavigate(settings);
|
||||
|
||||
Logging.LOG.info("Navigating to " + prevPage + ", pages: " + pages);
|
||||
LOG.info("Navigating to " + prevPage + ", pages: " + pages);
|
||||
displayer.navigateTo(prevPage, NavigationDirection.PREVIOUS);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,12 +31,11 @@ import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
* A class that checks the integrity of HMCL.
|
||||
@@ -132,7 +131,7 @@ public final class IntegrityChecker {
|
||||
LOG.info("Successfully verified current JAR");
|
||||
selfVerified = true;
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to verify myself, is the JAR corrupt?", e);
|
||||
LOG.warning("Failed to verify myself, is the JAR corrupt?", e);
|
||||
selfVerified = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,10 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public final class UpdateChecker {
|
||||
@@ -112,7 +111,7 @@ public final class UpdateChecker {
|
||||
result = checkUpdate(channel);
|
||||
LOG.info("Latest version (" + channel + ") is " + result);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to check for update", e);
|
||||
LOG.warning("Failed to check for update", e);
|
||||
}
|
||||
|
||||
RemoteVersion finalResult = result;
|
||||
|
||||
@@ -42,13 +42,12 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.checkFxUserThread;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class UpdateHandler {
|
||||
@@ -66,7 +65,7 @@ public final class UpdateHandler {
|
||||
try {
|
||||
performMigration();
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to perform migration", e);
|
||||
LOG.warning("Failed to perform migration", e);
|
||||
SwingUtils.showErrorDialog(i18n("fatal.apply_update_failure", Metadata.PUBLISH_URL) + "\n" + StringUtils.getStackTrace(e));
|
||||
}
|
||||
return true;
|
||||
@@ -81,7 +80,7 @@ public final class UpdateHandler {
|
||||
try {
|
||||
applyUpdate(Paths.get(args[1]));
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to apply update", e);
|
||||
LOG.warning("Failed to apply update", e);
|
||||
SwingUtils.showErrorDialog(i18n("fatal.apply_update_failure", Metadata.PUBLISH_URL) + "\n" + StringUtils.getStackTrace(e));
|
||||
}
|
||||
return true;
|
||||
@@ -108,7 +107,7 @@ public final class UpdateHandler {
|
||||
try {
|
||||
downloaded = Files.createTempFile("hmcl-update-", ".jar");
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to create temp file", e);
|
||||
LOG.warning("Failed to create temp file", e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -127,15 +126,15 @@ public final class UpdateHandler {
|
||||
}
|
||||
|
||||
requestUpdate(downloaded, getCurrentLocation());
|
||||
System.exit(0);
|
||||
Main.exit(0);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to update to " + version, e);
|
||||
LOG.warning("Failed to update to " + version, e);
|
||||
Platform.runLater(() -> Controllers.dialog(StringUtils.getStackTrace(e), i18n("update.failed"), MessageType.ERROR));
|
||||
}
|
||||
|
||||
} else {
|
||||
Exception e = executor.getException();
|
||||
LOG.log(Level.WARNING, "Failed to update to " + version, e);
|
||||
LOG.warning("Failed to update to " + version, e);
|
||||
if (e instanceof CancellationException) {
|
||||
Platform.runLater(() -> Controllers.showToast(i18n("message.cancelled")));
|
||||
} else {
|
||||
@@ -162,7 +161,7 @@ public final class UpdateHandler {
|
||||
Files.move(target, newFilename.get());
|
||||
target = newFilename.get();
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to move target", e);
|
||||
LOG.warning("Failed to move target", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +272,7 @@ public final class UpdateHandler {
|
||||
LOG.info("Successfully broke the force update feature");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to break the force update feature", e);
|
||||
LOG.warning("Failed to break the force update feature", e);
|
||||
} catch (JsonParseException e) {
|
||||
hmclVersionJson.toFile().delete();
|
||||
}
|
||||
|
||||
@@ -29,9 +29,8 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -67,14 +66,14 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
if (s.contains(entry.getKey())) {
|
||||
if (StringUtils.isNotBlank(entry.getValue())) {
|
||||
String info = entry.getValue();
|
||||
LOG.severe(info);
|
||||
LOG.error(info);
|
||||
try {
|
||||
Alert alert = new Alert(AlertType.INFORMATION, info);
|
||||
alert.setTitle(i18n("message.info"));
|
||||
alert.setHeaderText(i18n("message.info"));
|
||||
alert.showAndWait();
|
||||
} catch (Throwable t) {
|
||||
LOG.log(Level.SEVERE, "Unable to show message", t);
|
||||
LOG.error("Unable to show message", t);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -90,14 +89,14 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
LOG.log(Level.SEVERE, "Uncaught exception in thread " + t.getName(), e);
|
||||
LOG.error("Uncaught exception in thread " + t.getName(), e);
|
||||
|
||||
try {
|
||||
CrashReport report = new CrashReport(t, e);
|
||||
if (!report.shouldBeReport())
|
||||
return;
|
||||
|
||||
LOG.log(Level.SEVERE, report.getDisplayText());
|
||||
LOG.error(report.getDisplayText());
|
||||
Platform.runLater(() -> {
|
||||
if (checkThrowable(e)) {
|
||||
if (showCrashWindow) {
|
||||
@@ -109,8 +108,10 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
}
|
||||
});
|
||||
} catch (Throwable handlingException) {
|
||||
LOG.log(Level.SEVERE, "Unable to handle uncaught exception", handlingException);
|
||||
LOG.error("Unable to handle uncaught exception", handlingException);
|
||||
}
|
||||
|
||||
LOG.shutdown();
|
||||
}
|
||||
|
||||
private void reportToServer(CrashReport crashReport) {
|
||||
@@ -118,13 +119,13 @@ public final class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("crash_report", crashReport.getDisplayText());
|
||||
map.put("version", Metadata.VERSION);
|
||||
map.put("log", Logging.getLogs());
|
||||
map.put("log", LOG.getLogs());
|
||||
try {
|
||||
String response = NetworkUtils.doPost(NetworkUtils.toURL("https://hmcl.huangyuhui.net/hmcl/crash.php"), map);
|
||||
if (StringUtils.isNotBlank(response))
|
||||
LOG.log(Level.SEVERE, "Crash server response: " + response);
|
||||
LOG.error("Crash server response: " + response);
|
||||
} catch (IOException ex) {
|
||||
LOG.log(Level.SEVERE, "Unable to post HMCL server.", ex);
|
||||
LOG.error("Unable to post HMCL server.", ex);
|
||||
}
|
||||
});
|
||||
t.setDaemon(true);
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.jackhuang.hmcl.util;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
* Utility for Adding JavaFX to module path.
|
||||
|
||||
@@ -15,10 +15,9 @@ import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class NativePatcher {
|
||||
private NativePatcher() {
|
||||
@@ -37,7 +36,7 @@ public final class NativePatcher {
|
||||
|
||||
return natives.getOrDefault(p.toString(), Collections.emptyMap());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to load native library list", e);
|
||||
LOG.warning("Failed to load native library list", e);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -43,6 +43,7 @@ package org.jackhuang.hmcl.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.ui.SwingUtils;
|
||||
import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
@@ -62,12 +63,11 @@ import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
import static org.jackhuang.hmcl.Metadata.HMCL_DIRECTORY;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
import static org.jackhuang.hmcl.util.platform.JavaVersion.CURRENT_JAVA;
|
||||
|
||||
@@ -121,7 +121,7 @@ public final class SelfDependencyPatcher {
|
||||
Class.forName("netscape.javascript.JSObject", false, classLoader);
|
||||
Class.forName("org.w3c.dom.html.HTMLDocument", false, classLoader);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.WARNING, "Disable javafx.web because JRE is incomplete", e);
|
||||
LOG.warning("Disable javafx.web because JRE is incomplete", e);
|
||||
dependencies.removeIf(it -> "javafx.web".equals(it.module) || "javafx.media".equals(it.module));
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ public final class SelfDependencyPatcher {
|
||||
}
|
||||
} else {
|
||||
LOG.info("User choose not to download JavaFX");
|
||||
System.exit(0);
|
||||
Main.exit(0);
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@@ -20,13 +20,11 @@ package org.jackhuang.hmcl.util.i18n;
|
||||
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Level;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class I18n {
|
||||
|
||||
@@ -34,26 +32,34 @@ public final class I18n {
|
||||
}
|
||||
|
||||
private static volatile SupportedLocale locale = Locales.DEFAULT;
|
||||
private static volatile ResourceBundle resourceBundle = locale.getResourceBundle();
|
||||
private static volatile DateTimeFormatter dateTimeFormatter;
|
||||
|
||||
public static void setLocale(SupportedLocale locale) {
|
||||
I18n.locale = locale;
|
||||
resourceBundle = locale.getResourceBundle();
|
||||
dateTimeFormatter = null;
|
||||
}
|
||||
|
||||
public static SupportedLocale getCurrentLocale() {
|
||||
return locale;
|
||||
public static boolean isUseChinese() {
|
||||
return locale.getLocale() == Locale.CHINA;
|
||||
}
|
||||
|
||||
public static ResourceBundle getResourceBundle() {
|
||||
return getCurrentLocale().getResourceBundle();
|
||||
return resourceBundle;
|
||||
}
|
||||
|
||||
public static String getName(SupportedLocale locale) {
|
||||
return locale == Locales.DEFAULT ? resourceBundle.getString("lang.default") : locale.getResourceBundle().getString("lang");
|
||||
}
|
||||
|
||||
public static String i18n(String key, Object... formatArgs) {
|
||||
try {
|
||||
return String.format(getResourceBundle().getString(key), formatArgs);
|
||||
} catch (MissingResourceException e) {
|
||||
LOG.log(Level.SEVERE, "Cannot find key " + key + " in resource bundle", e);
|
||||
LOG.error("Cannot find key " + key + " in resource bundle", e);
|
||||
} catch (IllegalFormatException e) {
|
||||
LOG.log(Level.SEVERE, "Illegal format string, key=" + key + ", args=" + Arrays.toString(formatArgs), e);
|
||||
LOG.error("Illegal format string, key=" + key + ", args=" + Arrays.toString(formatArgs), e);
|
||||
}
|
||||
|
||||
return key + Arrays.toString(formatArgs);
|
||||
@@ -63,13 +69,18 @@ public final class I18n {
|
||||
try {
|
||||
return getResourceBundle().getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
LOG.log(Level.SEVERE, "Cannot find key " + key + " in resource bundle", e);
|
||||
LOG.error("Cannot find key " + key + " in resource bundle", e);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDateTime(Instant instant) {
|
||||
return getCurrentLocale().getDateTimeFormatter().format(instant);
|
||||
DateTimeFormatter formatter = dateTimeFormatter;
|
||||
if (formatter == null) {
|
||||
formatter = dateTimeFormatter = DateTimeFormatter.ofPattern(getResourceBundle().getString("world.time")).withZone(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
return formatter.format(instant);
|
||||
}
|
||||
|
||||
public static boolean hasKey(String key) {
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
@@ -34,7 +32,7 @@ public final class Locales {
|
||||
private Locales() {
|
||||
}
|
||||
|
||||
public static final SupportedLocale DEFAULT = new SupportedLocale(Locale.getDefault(), "lang.default");
|
||||
public static final SupportedLocale DEFAULT = new SupportedLocale(Locale.getDefault());
|
||||
|
||||
/**
|
||||
* English
|
||||
@@ -102,23 +100,10 @@ public final class Locales {
|
||||
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
||||
public static final class SupportedLocale {
|
||||
private final Locale locale;
|
||||
private final String name;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private DateTimeFormatter dateTimeFormatter;
|
||||
private ResourceBundle resourceBundle;
|
||||
|
||||
SupportedLocale(Locale locale) {
|
||||
this(locale, null);
|
||||
}
|
||||
|
||||
SupportedLocale(Locale locale, String name) {
|
||||
this.locale = locale;
|
||||
this.name = name;
|
||||
if (JavaVersion.CURRENT_JAVA.getParsedVersion() == JavaVersion.JAVA_8) {
|
||||
resourceBundle = ResourceBundle.getBundle("assets.lang.I18N", locale, UTF8Control.INSTANCE);
|
||||
} else {
|
||||
// UTF-8 is supported in Java 9+
|
||||
resourceBundle = ResourceBundle.getBundle("assets.lang.I18N", locale);
|
||||
}
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
@@ -126,20 +111,22 @@ public final class Locales {
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return resourceBundle;
|
||||
}
|
||||
ResourceBundle bundle = resourceBundle;
|
||||
|
||||
public DateTimeFormatter getDateTimeFormatter() {
|
||||
if (dateTimeFormatter == null) {
|
||||
dateTimeFormatter = DateTimeFormatter.ofPattern(resourceBundle.getString("world.time")).withZone(ZoneId.systemDefault());
|
||||
if (resourceBundle == null) {
|
||||
if (this != DEFAULT && this.locale == DEFAULT.locale) {
|
||||
bundle = DEFAULT.getResourceBundle();
|
||||
} else if (JavaVersion.CURRENT_JAVA.getParsedVersion() < 9) {
|
||||
bundle = ResourceBundle.getBundle("assets.lang.I18N", locale, UTF8Control.INSTANCE);
|
||||
} else {
|
||||
// Java 9+ uses UTF-8 as the default encoding for resource bundles
|
||||
bundle = ResourceBundle.getBundle("assets.lang.I18N", locale);
|
||||
}
|
||||
|
||||
resourceBundle = bundle;
|
||||
}
|
||||
|
||||
return dateTimeFormatter;
|
||||
}
|
||||
|
||||
public String getName(ResourceBundle newResourceBundle) {
|
||||
if (name == null) return resourceBundle.getString("lang");
|
||||
else return newResourceBundle.getString(name);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static final class TypeAdapter extends com.google.gson.TypeAdapter<SupportedLocale> {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jackhuang.hmcl.util.logging;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Glavo
|
||||
*/
|
||||
final class CallerFinder {
|
||||
private static final StackWalker WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
||||
private static final String PACKAGE_PREFIX = CallerFinder.class.getPackageName() + ".";
|
||||
private static final Predicate<StackWalker.StackFrame> PREDICATE = stackFrame -> !stackFrame.getClassName().startsWith(PACKAGE_PREFIX);
|
||||
private static final Function<Stream<StackWalker.StackFrame>, Optional<StackWalker.StackFrame>> FUNCTION = stream -> stream.filter(PREDICATE).findFirst();
|
||||
|
||||
static String getCaller() {
|
||||
return WALKER.walk(FUNCTION).map(it -> it.getClassName() + "." + it.getMethodName()).orElse(null);
|
||||
}
|
||||
|
||||
private CallerFinder() {
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 999 B |
|
Before Width: | Height: | Size: 912 B |
|
Before Width: | Height: | Size: 1001 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 861 B |
|
Before Width: | Height: | Size: 958 B |
|
Before Width: | Height: | Size: 988 B |
|
Before Width: | Height: | Size: 947 B |
@@ -37,8 +37,6 @@ about.thanks_to.gamerteam.statement=For providing the default background image.
|
||||
about.thanks_to.glavo.statement=Responsible for maintaining HMCL.
|
||||
about.thanks_to.zekerzhayard.statement=Contribute a lot of technical support to HMCL.
|
||||
about.thanks_to.zkitefly.statement=Responsible for maintaining documentation of HMCL.
|
||||
about.thanks_to.mcbbs=MCBBS (Minecraft Chinese Forum)
|
||||
about.thanks_to.mcbbs.statement=For providing mcbbs.net download mirror for Mainland China users.
|
||||
about.thanks_to.mcmod=mcmod.cn
|
||||
about.thanks_to.mcmod.statement=For providing Chinese translations and wiki for various mods.
|
||||
about.thanks_to.red_lnn.statement=For providing the default background image.
|
||||
@@ -143,8 +141,8 @@ account.portable=Portable Account
|
||||
account.skin=Skin
|
||||
account.skin.file=Skin File
|
||||
account.skin.model=Model
|
||||
account.skin.model.default=Classic (Steve)
|
||||
account.skin.model.slim=Slim (Alex)
|
||||
account.skin.model.default=Classic
|
||||
account.skin.model.slim=Slim
|
||||
account.skin.type.csl_api=Blessing Skin
|
||||
account.skin.type.csl_api.location=Address
|
||||
account.skin.type.csl_api.location.hint=CustomSkinAPI URL
|
||||
@@ -327,7 +325,6 @@ download.failed=Failed to download %1$s, response code: %2$d
|
||||
download.failed.empty=No versions are available, please click here to go back.
|
||||
download.failed.refresh=Unable to fetch version list. Please click here to retry.
|
||||
download.game=Game
|
||||
download.provider.mcbbs=MCBBS (https://www.mcbbs.net/)
|
||||
download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
|
||||
download.provider.mojang=Mojang (OptiFine is provided by BMCLAPI)
|
||||
download.provider.official=From Official Sources
|
||||
@@ -827,26 +824,39 @@ Keep in mind that you are not allowed to add mods and resource packs that are ex
|
||||
modpack.wizard.step.initialization.server=Click here for more tutorials for making a server modpack that can be automatically updated.
|
||||
|
||||
modrinth.category.adventure=Adventure
|
||||
modrinth.category.audio=Audio
|
||||
modrinth.category.blocks=Blocks
|
||||
modrinth.category.bukkit=Bukkit
|
||||
modrinth.category.bungeecord=BungeeCord
|
||||
modrinth.category.challenging=Challenging
|
||||
modrinth.category.core-shaders=Core Shaders
|
||||
modrinth.category.combat=Combat
|
||||
modrinth.category.cursed=Cursed
|
||||
modrinth.category.decoration=Decoration
|
||||
modrinth.category.economy=Economy
|
||||
modrinth.category.entities=Entities
|
||||
modrinth.category.environment=Environment
|
||||
modrinth.category.equipment=Equipment
|
||||
modrinth.category.fabric=Fabric
|
||||
modrinth.category.fonts=Fonts
|
||||
modrinth.category.food=Food
|
||||
modrinth.category.forge=Forge
|
||||
modrinth.category.game-mechanics=Game Mechanics
|
||||
modrinth.category.gui=GUI
|
||||
modrinth.category.items=Items
|
||||
modrinth.category.kitchen-sink=Kitchen-Sink
|
||||
modrinth.category.library=Library
|
||||
modrinth.category.lightweight=Lightweight
|
||||
modrinth.category.liteloader=LiteLoader
|
||||
modrinth.category.locale=Locale
|
||||
modrinth.category.magic=Magic
|
||||
modrinth.category.management=Management
|
||||
modrinth.category.minecraft=Minecraft
|
||||
modrinth.category.minigame=Minigame
|
||||
modrinth.category.misc=Misc
|
||||
modrinth.category.mobs=Mobs
|
||||
modrinth.category.modded=Modded
|
||||
modrinth.category.models=Models
|
||||
modrinth.category.modloader=Modloader
|
||||
modrinth.category.multiplayer=Multiplayer
|
||||
modrinth.category.neoforge=NeoForge
|
||||
@@ -855,19 +865,32 @@ modrinth.category.paper=Paper
|
||||
modrinth.category.purpur=Purpur
|
||||
modrinth.category.quests=Quests
|
||||
modrinth.category.quilt=Quilt
|
||||
modrinth.category.realistic=Realistic
|
||||
modrinth.category.rift=Rift
|
||||
modrinth.category.simplistic=Simplistic
|
||||
modrinth.category.social=Social
|
||||
modrinth.category.spigot=Spigot
|
||||
modrinth.category.sponge=Sponge
|
||||
modrinth.category.storage=Storage
|
||||
modrinth.category.technology=Technology
|
||||
modrinth.category.themed=Themed
|
||||
modrinth.category.transportation=Transportation
|
||||
modrinth.category.tweaks=Tweaks
|
||||
modrinth.category.utility=Utility
|
||||
modrinth.category.vanilla-like=Vanilla-like
|
||||
modrinth.category.velocity=Velocity
|
||||
modrinth.category.waterfall=Waterfall
|
||||
modrinth.category.worldgen=Worldgen
|
||||
modrinth.category.datapack=Datapack
|
||||
modrinth.category.folia=Folia
|
||||
modrinth.category.8x-=8x-
|
||||
modrinth.category.16x=16x
|
||||
modrinth.category.32x=32x
|
||||
modrinth.category.48x=48x
|
||||
modrinth.category.64x=64x
|
||||
modrinth.category.128x=128x
|
||||
modrinth.category.256x=256x
|
||||
modrinth.category.512x+=512x+
|
||||
|
||||
mods=Mods
|
||||
mods.add=Add Mods
|
||||
|
||||
@@ -36,8 +36,6 @@ about.thanks_to.gamerteam.statement=Por proporcionar la imagen de fondo por defe
|
||||
about.thanks_to.glavo.statement=Aportar mucho apoyo técnico a HMCL.
|
||||
about.thanks_to.zekerzhayard.statement=Aportar mucho apoyo técnico a HMCL.
|
||||
about.thanks_to.zkitefly.statement=Aportar mucho apoyo técnico a HMCL.
|
||||
about.thanks_to.mcbbs=MCBBS (Foro chino de Minecraft)
|
||||
about.thanks_to.mcbbs.statement=Por proporcionar un espejo de descarga de mcbbs.net para los usuarios de China continental.
|
||||
about.thanks_to.mcmod=mcmod.cn
|
||||
about.thanks_to.mcmod.statement=Por facilitar las traducciones al chino y el wiki de varios mods.
|
||||
about.thanks_to.red_lnn.statement=Por proporcionar la imagen de fondo por defecto.
|
||||
@@ -125,8 +123,8 @@ account.password=Contraseña
|
||||
account.skin=Skin
|
||||
account.skin.file=Archivo de skin
|
||||
account.skin.model=Modelo
|
||||
account.skin.model.default=Clásico (Steve)
|
||||
account.skin.model.slim=Delgado (Alex)
|
||||
account.skin.model.default=Clásico
|
||||
account.skin.model.slim=Delgado
|
||||
account.skin.type.csl_api=Blessing skin
|
||||
account.skin.type.csl_api.location=URL
|
||||
account.skin.type.csl_api.location.hint=CustomSkinAPI URL
|
||||
@@ -304,7 +302,6 @@ download.failed=Falló la descarga de %1$s, código de respuesta: %2$d
|
||||
download.failed.empty=No hay versiones disponibles, por favor haga clic aquí para volver.
|
||||
download.failed.refresh=No se ha podido obtener la lista de versiones. Por favor, haga clic aquí para volver a intentarlo.
|
||||
download.game=Juego
|
||||
download.provider.mcbbs=MCBBS (https://www.mcbbs.net/)
|
||||
download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
|
||||
download.provider.mojang=Mojang (OptiFine es proporcionado por BMCLAPI)
|
||||
download.provider.official=De fuentes oficiales
|
||||
|
||||
@@ -34,8 +34,6 @@ about.thanks_to.gamerteam.statement=デフォルトの背景画像プロバイ
|
||||
about.thanks_to.glavo.statement=HMCLに多くのテクニカルサポートを提供
|
||||
about.thanks_to.zekerzhayard.statement=HMCLに多くのテクニカルサポートを提供
|
||||
about.thanks_to.zkitefly.statement=HMCLに多くのテクニカルサポートを提供。
|
||||
about.thanks_to.mcbbs=MCBBS
|
||||
about.thanks_to.mcbbs.statement=MCBBSダウンロードソースプロバイダー。
|
||||
about.thanks_to.mcmod=mcmod.cn
|
||||
about.thanks_to.mcmod.statement=Mod中国語の名前翻訳プロバイダー。
|
||||
about.thanks_to.red_lnn.statement=デフォルトの背景画像プロバイダー。
|
||||
@@ -112,8 +110,8 @@ account.password=パスワード
|
||||
account.skin=スキン
|
||||
account.skin.file=スキンイメージファイル
|
||||
account.skin.model=モデル
|
||||
account.skin.model.default=Classic (Steve)
|
||||
account.skin.model.slim=Slim (Alex)
|
||||
account.skin.model.default=Classic
|
||||
account.skin.model.slim=Slim
|
||||
account.skin.type.csl_api=Blessing Skin
|
||||
account.skin.type.csl_api.location=アドレス
|
||||
account.skin.type.csl_api.location.hint=CustomSkinAPI
|
||||
@@ -286,7 +284,6 @@ download.failed=%1$s のダウンロードに失敗しました、応答コー
|
||||
download.failed.empty=候補者なし。戻るにはここをクリックしてください。
|
||||
download.failed.refresh=バージョンリストをダウンロードできません。ここをクリックして再試行してください。
|
||||
download.game=ゲームのダウンロード
|
||||
download.provider.mcbbs=MCBBS(https://www.mcbbs.net/)
|
||||
download.provider.bmclapi=BMCLAPI(ミラーソース)
|
||||
download.provider.mojang=Mojang(OptiFineはBMCLAPIにより提供されます) 推奨
|
||||
download.provider.official=公式ソースからロード
|
||||
|
||||
@@ -36,8 +36,6 @@ about.thanks_to.gamerteam.statement=За предоставление фонов
|
||||
about.thanks_to.glavo.statement=Оказал большую техническую поддержку HMCL.
|
||||
about.thanks_to.zekerzhayard.statement=Оказал большую техническую поддержку HMCL.
|
||||
about.thanks_to.zkitefly.statement=Оказал большую техническую поддержку HMCL.
|
||||
about.thanks_to.mcbbs=MCBBS (Minecraft Chinese Forum)
|
||||
about.thanks_to.mcbbs.statement=За предоставление зеркала скачивания MCBBS.NET для пользователей Китая.
|
||||
about.thanks_to.mcmod=mcmod.cn
|
||||
about.thanks_to.mcmod.statement=За предоставление перевода на китайский и вики для различных модов.
|
||||
about.thanks_to.red_lnn.statement=За предоставление фонового изображения.
|
||||
@@ -120,8 +118,8 @@ account.password=Пароль
|
||||
account.skin=Скин
|
||||
account.skin.file=Файл скина
|
||||
account.skin.model=Модель
|
||||
account.skin.model.default=Классическая (Стив)
|
||||
account.skin.model.slim=Стройная (Алекс)
|
||||
account.skin.model.default=Классическая
|
||||
account.skin.model.slim=Стройная
|
||||
account.skin.type.csl_api=Blessing Skin
|
||||
account.skin.type.csl_api.location=Адрес
|
||||
account.skin.type.csl_api.location.hint=URL-адрес CustomSkinAPI
|
||||
@@ -303,7 +301,6 @@ download.failed=Не удаётся скачать %1$s, код ответа\: %
|
||||
download.failed.empty=Версий нет. Нажмите здесь, чтобы вернуться назад.
|
||||
download.failed.refresh=Не удаётся получить список версий. Нажмите здесь, чтобы повторить попытку.
|
||||
download.game=Игра
|
||||
download.provider.mcbbs=MCBBS (https://www.mcbbs.net/)
|
||||
download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
|
||||
download.provider.mojang=Mojang (OptiFine is provided by BMCLAPI)
|
||||
download.provider.official=Из официальных источников
|
||||
|
||||
@@ -35,8 +35,6 @@ about.thanks_to.gamerteam.statement=提供預設背景圖
|
||||
about.thanks_to.glavo.statement=負責 HMCL 的日常維護
|
||||
about.thanks_to.zekerzhayard.statement=為 HMCL 貢獻許多技術支持
|
||||
about.thanks_to.zkitefly.statement=負責維護 HMCL 的文檔
|
||||
about.thanks_to.mcbbs=MCBBS 我的世界中文論壇
|
||||
about.thanks_to.mcbbs.statement=提供 MCBBS 下載地點
|
||||
about.thanks_to.mcmod=MC 百科
|
||||
about.thanks_to.mcmod.statement=提供 Mod 中文名映射表與 Mod 百科
|
||||
about.thanks_to.red_lnn.statement=提供預設背景圖
|
||||
@@ -152,8 +150,8 @@ account.portable=便攜帳戶
|
||||
account.skin=皮膚
|
||||
account.skin.file=皮膚圖片檔案
|
||||
account.skin.model=模型
|
||||
account.skin.model.default=經典(Steve)
|
||||
account.skin.model.slim=苗條(Alex)
|
||||
account.skin.model.default=經典
|
||||
account.skin.model.slim=苗條
|
||||
account.skin.type.csl_api=Blessing Skin 伺服器
|
||||
account.skin.type.csl_api.location=伺服器位址
|
||||
account.skin.type.csl_api.location.hint=CustomSkinAPI 位址
|
||||
@@ -336,7 +334,6 @@ download.failed=下載失敗: %1$s,錯誤碼:%2$d
|
||||
download.failed.empty=沒有能安裝的版本,按一下此處返回。
|
||||
download.failed.refresh=載入版本列表失敗,按一下此處重試。
|
||||
download.game=新遊戲
|
||||
download.provider.mcbbs=我的世界中文論壇 (MCBBS, https://www.mcbbs.net/)
|
||||
download.provider.bmclapi=BMCLAPI (bangbang93,https://bmclapi2.bangbang93.com/)
|
||||
download.provider.mojang=官方伺服器 (OptiFine 自動安裝的下載來源是 BMCLAPI)
|
||||
download.provider.official=儘量使用官方源(最新,但可能加載慢)
|
||||
@@ -511,7 +508,7 @@ install.installer.forge=Forge
|
||||
install.installer.neoforge=NeoForge
|
||||
install.installer.game=Minecraft
|
||||
install.installer.incompatible=與 %s 不相容
|
||||
install.installer.install=安裝%s
|
||||
install.installer.install=安裝 %s
|
||||
install.installer.install_offline=從本機檔案安裝或升級
|
||||
install.installer.install_offline.extension=Forge/OptiFine 安裝器
|
||||
install.installer.install_offline.tooltip=支援匯入已經下載好的 Forge/OptiFine 安裝器
|
||||
@@ -703,26 +700,39 @@ modpack.wizard.step.initialization.warning=在製作模組包前,請您確認
|
||||
modpack.wizard.step.initialization.server=點選此處查看有關伺服器自動更新模組包的製作教學
|
||||
|
||||
modrinth.category.adventure=冒險
|
||||
modrinth.category.audio=聲音
|
||||
modrinth.category.blocks=方塊
|
||||
modrinth.category.bukkit=Bukkit
|
||||
modrinth.category.bungeecord=BungeeCord
|
||||
modrinth.category.challenging=高難度
|
||||
modrinth.category.core-shaders=覈心著色器
|
||||
modrinth.category.combat=戰鬥
|
||||
modrinth.category.cursed=Cursed
|
||||
modrinth.category.decoration=裝飾
|
||||
modrinth.category.economy=經濟
|
||||
modrinth.category.entities=實體
|
||||
modrinth.category.environment=環境
|
||||
modrinth.category.equipment=裝備
|
||||
modrinth.category.fabric=Fabric
|
||||
modrinth.category.fonts=字體
|
||||
modrinth.category.food=食物
|
||||
modrinth.category.forge=Forge
|
||||
modrinth.category.game-mechanics=遊戲機制
|
||||
modrinth.category.gui=GUI
|
||||
modrinth.category.items=物品
|
||||
modrinth.category.kitchen-sink=大雜燴
|
||||
modrinth.category.library=支持庫
|
||||
modrinth.category.lightweight=輕量
|
||||
modrinth.category.liteloader=LiteLoader
|
||||
modrinth.category.locale=在地化
|
||||
modrinth.category.magic=魔法
|
||||
modrinth.category.management=管理
|
||||
modrinth.category.minecraft=Minecraft
|
||||
modrinth.category.minigame=小遊戲
|
||||
modrinth.category.misc=其他
|
||||
modrinth.category.mobs=生物
|
||||
modrinth.category.modded=Modded
|
||||
modrinth.category.models=模型
|
||||
modrinth.category.modloader=Modloader
|
||||
modrinth.category.multiplayer=多人
|
||||
modrinth.category.neoforge=NeoForge
|
||||
@@ -731,14 +741,19 @@ modrinth.category.paper=Paper
|
||||
modrinth.category.purpur=Purpur
|
||||
modrinth.category.quests=任務
|
||||
modrinth.category.quilt=Quilt
|
||||
modrinth.category.realistic=寫實
|
||||
modrinth.category.rift=Rift
|
||||
modrinth.category.simplistic=簡單
|
||||
modrinth.category.social=社交
|
||||
modrinth.category.spigot=Spigot
|
||||
modrinth.category.sponge=Sponge
|
||||
modrinth.category.storage=儲存
|
||||
modrinth.category.technology=科技
|
||||
modrinth.category.themed=主題
|
||||
modrinth.category.transportation=運輸
|
||||
modrinth.category.tweaks=優化
|
||||
modrinth.category.utility=實用
|
||||
modrinth.category.vanilla-like=類原生
|
||||
modrinth.category.velocity=Velocity
|
||||
modrinth.category.waterfall=Waterfall
|
||||
modrinth.category.worldgen=世界生成
|
||||
|
||||
@@ -35,8 +35,6 @@ about.thanks_to.gamerteam.statement=提供默认背景图
|
||||
about.thanks_to.glavo.statement=负责 HMCL 的日常维护
|
||||
about.thanks_to.zekerzhayard.statement=为 HMCL 贡献许多技术支持
|
||||
about.thanks_to.zkitefly.statement=负责维护 HMCL 的文档
|
||||
about.thanks_to.mcbbs=MCBBS 我的世界中文论坛
|
||||
about.thanks_to.mcbbs.statement=提供 MCBBS 下载源
|
||||
about.thanks_to.mcmod=MC 百科
|
||||
about.thanks_to.mcmod.statement=提供模组中文名映射表与 Mod 百科
|
||||
about.thanks_to.red_lnn.statement=提供默认背景图
|
||||
@@ -153,8 +151,8 @@ account.portable=便携账户
|
||||
account.skin=皮肤
|
||||
account.skin.file=皮肤图片文件
|
||||
account.skin.model=模型
|
||||
account.skin.model.default=经典(Steve)
|
||||
account.skin.model.slim=苗条(Alex)
|
||||
account.skin.model.default=经典
|
||||
account.skin.model.slim=苗条
|
||||
account.skin.type.csl_api=Blessing Skin 服务器
|
||||
account.skin.type.csl_api.location=服务器地址
|
||||
account.skin.type.csl_api.location.hint=CustomSkinAPI 地址
|
||||
@@ -337,7 +335,6 @@ download.failed=下载失败: %1$s,错误码:%2$d
|
||||
download.failed.empty=[没有可供安装的版本,点击此处返回]
|
||||
download.failed.refresh=[加载版本列表失败,点击此处重试]
|
||||
download.game=新游戏
|
||||
download.provider.mcbbs=我的世界中文论坛 (MCBBS, https://www.mcbbs.net)
|
||||
download.provider.bmclapi=BMCLAPI(bangbang93,https://bmclapi2.bangbang93.com)
|
||||
download.provider.mojang=官方(OptiFine 自动安装使用 BMCLAPI 下载源)
|
||||
download.provider.official=尽量使用官方源(最新,但可能加载慢)
|
||||
@@ -702,26 +699,39 @@ modpack.wizard.step.initialization.warning=在制作整合包前,请您确认
|
||||
modpack.wizard.step.initialization.server=点击此处查看有关服务器自动更新整合包的制作教程
|
||||
|
||||
modrinth.category.adventure=冒险
|
||||
modrinth.category.audio=声音
|
||||
modrinth.category.blocks=方块
|
||||
modrinth.category.bukkit=Bukkit
|
||||
modrinth.category.bungeecord=BungeeCord
|
||||
modrinth.category.challenging=高难度
|
||||
modrinth.category.core-shaders=核心着色器
|
||||
modrinth.category.combat=战斗
|
||||
modrinth.category.cursed=Cursed
|
||||
modrinth.category.decoration=装饰
|
||||
modrinth.category.economy=经济
|
||||
modrinth.category.entities=实体
|
||||
modrinth.category.environment=环境
|
||||
modrinth.category.equipment=装备
|
||||
modrinth.category.fabric=Fabric
|
||||
modrinth.category.fonts=字体
|
||||
modrinth.category.food=食物
|
||||
modrinth.category.forge=Forge
|
||||
modrinth.category.game-mechanics=游戏机制
|
||||
modrinth.category.gui=GUI
|
||||
modrinth.category.items=物品
|
||||
modrinth.category.kitchen-sink=大杂烩
|
||||
modrinth.category.library=支持库
|
||||
modrinth.category.lightweight=轻量
|
||||
modrinth.category.liteloader=LiteLoader
|
||||
modrinth.category.locale=本地化
|
||||
modrinth.category.magic=魔法
|
||||
modrinth.category.management=管理
|
||||
modrinth.category.minecraft=Minecraft
|
||||
modrinth.category.minigame=小游戏
|
||||
modrinth.category.misc=其他
|
||||
modrinth.category.mobs=生物
|
||||
modrinth.category.modded=Modded
|
||||
modrinth.category.models=模型
|
||||
modrinth.category.modloader=Modloader
|
||||
modrinth.category.multiplayer=多人
|
||||
modrinth.category.neoforge=NeoForge
|
||||
@@ -730,14 +740,19 @@ modrinth.category.paper=Paper
|
||||
modrinth.category.purpur=Purpur
|
||||
modrinth.category.quests=任务
|
||||
modrinth.category.quilt=Quilt
|
||||
modrinth.category.realistic=写实
|
||||
modrinth.category.rift=Rift
|
||||
modrinth.category.simplistic=简单
|
||||
modrinth.category.social=社交
|
||||
modrinth.category.spigot=Spigot
|
||||
modrinth.category.sponge=Sponge
|
||||
modrinth.category.storage=存储
|
||||
modrinth.category.technology=科技
|
||||
modrinth.category.themed=主题
|
||||
modrinth.category.transportation=运输
|
||||
modrinth.category.tweaks=优化
|
||||
modrinth.category.utility=实用
|
||||
modrinth.category.vanilla-like=类原生
|
||||
modrinth.category.velocity=Velocity
|
||||
modrinth.category.waterfall=Waterfall
|
||||
modrinth.category.worldgen=世界生成
|
||||
|
||||
@@ -8,6 +8,7 @@ import moe.mickey.minecraft.skin.fx.SkinCanvas;
|
||||
import moe.mickey.minecraft.skin.fx.SkinCanvasSupport;
|
||||
import moe.mickey.minecraft.skin.fx.animation.SkinAniRunning;
|
||||
import moe.mickey.minecraft.skin.fx.animation.SkinAniWavingArms;
|
||||
import org.jackhuang.hmcl.game.TexturesLoader;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -16,7 +17,7 @@ public class Test extends Application {
|
||||
public static final String TITLE = "FX - Minecraft skin preview";
|
||||
|
||||
public static SkinCanvas createSkinCanvas() {
|
||||
SkinCanvas canvas = new SkinCanvas(SkinCanvas.STEVE, 400, 400, true);
|
||||
SkinCanvas canvas = new SkinCanvas(TexturesLoader.getDefaultSkinImage(), 400, 400, true);
|
||||
canvas.getAnimationPlayer().addSkinAnimation(new SkinAniWavingArms(100, 2000, 7.5, canvas), new SkinAniRunning(100, 100, 30, canvas));
|
||||
FunctionHelper.alwaysB(Consumer<SkinCanvas>::accept, canvas, new SkinCanvasSupport.Mouse(.5), new SkinCanvasSupport.Drag(TITLE));
|
||||
return canvas;
|
||||
|
||||
@@ -32,9 +32,8 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvider {
|
||||
|
||||
@@ -139,7 +138,7 @@ public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvide
|
||||
try {
|
||||
return Optional.of(AuthlibInjectorArtifactInfo.from(path));
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
|
||||
LOG.warning("Bad authlib-injector artifact", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jackhuang.hmcl.auth.authlibinjector;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
@@ -60,6 +59,7 @@ public class AuthlibInjectorServer implements Observable {
|
||||
try {
|
||||
url = addHttpsIfMissing(url);
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestProperty("Accept-Language", Locale.getDefault().toLanguageTag());
|
||||
|
||||
String ali = conn.getHeaderField("x-authlib-injector-api-location");
|
||||
if (ali != null) {
|
||||
@@ -68,6 +68,7 @@ public class AuthlibInjectorServer implements Observable {
|
||||
conn.disconnect();
|
||||
url = absoluteAli.toString();
|
||||
conn = (HttpURLConnection) absoluteAli.openConnection();
|
||||
conn.setRequestProperty("Accept-Language", Locale.getDefault().toLanguageTag());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ public class AuthlibInjectorServer implements Observable {
|
||||
try {
|
||||
instance.setMetadataResponse(jsonObj.get("metadataResponse").getAsString(), jsonObj.get("metadataTimestamp").getAsLong());
|
||||
} catch (JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Ignoring malformed metadata response cache: " + jsonObj.get("metadataResponse"), e);
|
||||
LOG.warning("Ignoring malformed metadata response cache: " + jsonObj.get("metadataResponse"), e);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.auth.authlibinjector;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class SimpleAuthlibInjectorArtifactProvider implements AuthlibInjectorArtifactProvider {
|
||||
|
||||
@@ -42,7 +41,7 @@ public class SimpleAuthlibInjectorArtifactProvider implements AuthlibInjectorArt
|
||||
try {
|
||||
return Optional.of(getArtifactInfo());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
|
||||
LOG.warning("Bad authlib-injector artifact", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,9 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class MicrosoftAccount extends OAuthAccount {
|
||||
|
||||
@@ -142,7 +141,7 @@ public class MicrosoftAccount extends OAuthAccount {
|
||||
try {
|
||||
return YggdrasilService.getTextures(it);
|
||||
} catch (ServerResponseMalformedException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse texture payload", e);
|
||||
LOG.warning("Failed to parse texture payload", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -39,13 +39,12 @@ import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public class MicrosoftService {
|
||||
@@ -62,7 +61,7 @@ public class MicrosoftService {
|
||||
this.profileRepository = new ObservableOptionalCache<>(uuid -> {
|
||||
LOG.info("Fetching properties of " + uuid);
|
||||
return getCompleteGameProfile(uuid);
|
||||
}, (uuid, e) -> LOG.log(Level.WARNING, "Failed to fetch properties of " + uuid, e), POOL);
|
||||
}, (uuid, e) -> LOG.warning("Failed to fetch properties of " + uuid, e), POOL);
|
||||
}
|
||||
|
||||
public ObservableOptionalCache<UUID, CompleteGameProfile, AuthenticationException> getProfileRepository() {
|
||||
@@ -97,7 +96,7 @@ public class MicrosoftService {
|
||||
}
|
||||
|
||||
if (response.displayClaims == null || response.displayClaims.xui == null || response.displayClaims.xui.size() == 0 || !response.displayClaims.xui.get(0).containsKey("uhs")) {
|
||||
LOG.log(Level.WARNING, "Unrecognized xbox authorization response " + GSON.toJson(response));
|
||||
LOG.warning("Unrecognized xbox authorization response " + GSON.toJson(response));
|
||||
throw new NoXuiException();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package org.jackhuang.hmcl.auth.microsoft;
|
||||
|
||||
import org.jackhuang.hmcl.auth.AuthInfo;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -45,7 +45,7 @@ public class MicrosoftSession {
|
||||
this.user = user;
|
||||
this.profile = profile;
|
||||
|
||||
if (accessToken != null) Logging.registerAccessToken(accessToken);
|
||||
if (accessToken != null) Logger.registerAccessToken(accessToken);
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorArtifactInfo;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorArtifactProvider;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloadException;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.Texture;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.TextureModel;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.TextureType;
|
||||
import org.jackhuang.hmcl.game.Arguments;
|
||||
import org.jackhuang.hmcl.game.LaunchOptions;
|
||||
@@ -101,14 +100,7 @@ public class OfflineAccount extends Account {
|
||||
}
|
||||
|
||||
protected boolean loadAuthlibInjector(Skin skin) {
|
||||
if (skin == null) return false;
|
||||
if (skin.getType() == Skin.Type.DEFAULT) return false;
|
||||
TextureModel defaultModel = TextureModel.detectUUID(getUUID());
|
||||
if (skin.getType() == Skin.Type.ALEX && defaultModel == TextureModel.ALEX ||
|
||||
skin.getType() == Skin.Type.STEVE && defaultModel == TextureModel.STEVE) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return skin != null && skin.getType() != Skin.Type.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hmcl.auth.offline;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import javafx.scene.image.Image;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.TextureModel;
|
||||
import org.jackhuang.hmcl.task.FetchTask;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
@@ -39,7 +40,6 @@ import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
@@ -99,12 +99,6 @@ public class Skin {
|
||||
}
|
||||
}
|
||||
|
||||
private static Function<Type, InputStream> defaultSkinLoader = null;
|
||||
|
||||
public static void registerDefaultSkinLoader(Function<Type, InputStream> defaultSkinLoader0) {
|
||||
defaultSkinLoader = defaultSkinLoader0;
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
private final String cslApi;
|
||||
private final TextureModel textureModel;
|
||||
@@ -128,7 +122,7 @@ public class Skin {
|
||||
}
|
||||
|
||||
public TextureModel getTextureModel() {
|
||||
return textureModel == null ? TextureModel.STEVE : textureModel;
|
||||
return textureModel == null ? TextureModel.WIDE : textureModel;
|
||||
}
|
||||
|
||||
public String getLocalSkinPath() {
|
||||
@@ -152,11 +146,14 @@ public class Skin {
|
||||
case STEVE:
|
||||
case SUNNY:
|
||||
case ZURI:
|
||||
if (defaultSkinLoader == null) {
|
||||
return Task.supplyAsync(() -> null);
|
||||
}
|
||||
TextureModel model = type == Type.ALEX ? TextureModel.ALEX : TextureModel.STEVE;
|
||||
return Task.supplyAsync(() -> new LoadedSkin(model, Texture.loadTexture(defaultSkinLoader.apply(type)), null));
|
||||
TextureModel model = this.textureModel != null ? this.textureModel : type == Type.ALEX ? TextureModel.SLIM : TextureModel.WIDE;
|
||||
String resource = (model == TextureModel.SLIM ? "/assets/img/skin/slim/" : "/assets/img/skin/wide/") + type.name().toLowerCase(Locale.ROOT) + ".png";
|
||||
|
||||
return Task.supplyAsync(() -> new LoadedSkin(
|
||||
model,
|
||||
Texture.loadTexture(new Image(resource)),
|
||||
null
|
||||
));
|
||||
case LOCAL_FILE:
|
||||
return Task.supplyAsync(() -> {
|
||||
Texture skin = null, cape = null;
|
||||
@@ -227,16 +224,7 @@ public class Skin {
|
||||
String localSkinPath = tryCast(storage.get("localSkinPath"), String.class).orElse(null);
|
||||
String localCapePath = tryCast(storage.get("localCapePath"), String.class).orElse(null);
|
||||
|
||||
TextureModel model;
|
||||
if ("default".equals(textureModel)) {
|
||||
model = TextureModel.STEVE;
|
||||
} else if ("slim".equals(textureModel)) {
|
||||
model = TextureModel.ALEX;
|
||||
} else {
|
||||
model = TextureModel.STEVE;
|
||||
}
|
||||
|
||||
return new Skin(type, cslApi, model, localSkinPath, localCapePath);
|
||||
return new Skin(type, cslApi, "slim".equals(textureModel) ? TextureModel.SLIM : TextureModel.WIDE, localSkinPath, localCapePath);
|
||||
}
|
||||
|
||||
private static class FetchBytesTask extends FetchTask<InputStream> {
|
||||
@@ -327,9 +315,9 @@ public class Skin {
|
||||
@Nullable
|
||||
public TextureModel getModel() {
|
||||
if (textures != null && textures.slim != null) {
|
||||
return TextureModel.ALEX;
|
||||
return TextureModel.SLIM;
|
||||
} else if (textures != null && textures.defaultSkin != null) {
|
||||
return TextureModel.STEVE;
|
||||
return TextureModel.WIDE;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -351,9 +339,9 @@ public class Skin {
|
||||
|
||||
public String getHash() {
|
||||
TextureModel model = getModel();
|
||||
if (model == TextureModel.ALEX)
|
||||
if (model == TextureModel.SLIM)
|
||||
return getAlexModelHash();
|
||||
else if (model == TextureModel.STEVE)
|
||||
else if (model == TextureModel.WIDE)
|
||||
return getSteveModelHash();
|
||||
else
|
||||
return null;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class YggdrasilServer extends HttpServer {
|
||||
public Object toCompleteResponse(String rootUrl) {
|
||||
Map<String, Object> realTextures = new HashMap<>();
|
||||
if (skin != null && skin.getSkin() != null) {
|
||||
if (skin.getModel() == TextureModel.ALEX) {
|
||||
if (skin.getModel() == TextureModel.SLIM) {
|
||||
realTextures.put("SKIN", mapOf(
|
||||
pair("url", rootUrl + "/textures/" + skin.getSkin().getHash()),
|
||||
pair("metadata", mapOf(
|
||||
|
||||
@@ -17,27 +17,12 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.auth.yggdrasil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public enum TextureModel {
|
||||
STEVE("default"), ALEX("slim");
|
||||
WIDE("default"), SLIM("slim");
|
||||
|
||||
public final String modelName;
|
||||
|
||||
TextureModel(String modelName) {
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public static TextureModel detectModelName(Map<String, String> metadata) {
|
||||
if (metadata != null && "slim".equals(metadata.get("model"))) {
|
||||
return ALEX;
|
||||
} else {
|
||||
return STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
public static TextureModel detectUUID(UUID uuid) {
|
||||
return (uuid.hashCode() & 1) == 1 ? ALEX : STEVE;
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,9 @@ import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public abstract class YggdrasilAccount extends ClassicAccount {
|
||||
|
||||
@@ -197,7 +196,7 @@ public abstract class YggdrasilAccount extends ClassicAccount {
|
||||
try {
|
||||
return YggdrasilService.getTextures(it);
|
||||
} catch (ServerResponseMalformedException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse texture payload", e);
|
||||
LOG.warning("Failed to parse texture payload", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -40,13 +40,12 @@ import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public class YggdrasilService {
|
||||
@@ -63,7 +62,7 @@ public class YggdrasilService {
|
||||
LOG.info("Fetching properties of " + uuid + " from " + provider);
|
||||
return getCompleteGameProfile(uuid);
|
||||
},
|
||||
(uuid, e) -> LOG.log(Level.WARNING, "Failed to fetch properties of " + uuid + " from " + provider, e),
|
||||
(uuid, e) -> LOG.warning("Failed to fetch properties of " + uuid + " from " + provider, e),
|
||||
POOL);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.jackhuang.hmcl.auth.yggdrasil;
|
||||
import com.google.gson.Gson;
|
||||
import org.jackhuang.hmcl.auth.AuthInfo;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class YggdrasilSession {
|
||||
this.availableProfiles = availableProfiles;
|
||||
this.userProperties = userProperties;
|
||||
|
||||
if (accessToken != null) Logging.registerAccessToken(accessToken);
|
||||
if (accessToken != null) Logger.registerAccessToken(accessToken);
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
|
||||
@@ -36,9 +36,10 @@ import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class DefaultCacheRepository extends CacheRepository {
|
||||
private Path librariesDir;
|
||||
private Path indexFile;
|
||||
@@ -67,7 +68,7 @@ public class DefaultCacheRepository extends CacheRepository {
|
||||
else
|
||||
index = new Index();
|
||||
} catch (IOException | JsonParseException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to read index file", e);
|
||||
LOG.warning("Unable to read index file", e);
|
||||
index = new Index();
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
@@ -105,7 +106,7 @@ public class DefaultCacheRepository extends CacheRepository {
|
||||
// or we will not cache the library
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + jar, e);
|
||||
LOG.warning("Unable to calc hash value of file " + jar, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@ public class DefaultCacheRepository extends CacheRepository {
|
||||
try {
|
||||
FileUtils.writeText(indexFile, JsonUtils.GSON.toJson(index));
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Unable to save index.json", e);
|
||||
LOG.error("Unable to save index.json", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
@@ -33,11 +32,11 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public class MaintainTask extends Task<Version> {
|
||||
private final GameRepository repository;
|
||||
@@ -164,7 +163,7 @@ public class MaintainTask extends Task<Version> {
|
||||
Files.createDirectories(libraryPath.getParent());
|
||||
Files.copy(input, libraryPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Unable to unpack HMCLTransformerDiscoveryService", e);
|
||||
LOG.warning("Unable to unpack HMCLTransformerDiscoveryService", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||