HMCLKotlin project
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<gradle-project-properties>
|
||||
<!--DO NOT EDIT THIS FILE! - Used by the Gradle plugin of NetBeans.-->
|
||||
<target-platform-name>j2se</target-platform-name>
|
||||
<target-platform>1.8</target-platform>
|
||||
<source-level>1.8</source-level>
|
||||
<common-tasks>
|
||||
<task>
|
||||
<display-name>launch4j</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="yes">launch4j</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
<task>
|
||||
<display-name>createApp</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="yes">createApp</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
</common-tasks>
|
||||
<script-platform>
|
||||
<spec-name>j2se</spec-name>
|
||||
<spec-version>1.8</spec-version>
|
||||
</script-platform>
|
||||
<license-header>
|
||||
<name>GNU General Public License</name>
|
||||
<template>license-header.txt</template>
|
||||
<property name="organization">huangyuhui</property>
|
||||
</license-header>
|
||||
</gradle-project-properties>
|
||||
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_install:
|
||||
- chmod +x gradlew
|
||||
script: "bash ./gradlew clean build --stacktrace"
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.gradle/caches/"
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,197 +1,4 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.Pack200
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import java.security.MessageDigest
|
||||
import java.util.jar.JarOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
plugins {
|
||||
id "edu.sc.seis.macAppBundle" version "2.1.6"
|
||||
id "me.tatarka.retrolambda" version "3.5.0"
|
||||
id 'edu.sc.seis.launch4j' version '2.3.0'
|
||||
//id "org.jetbrains.kotlin.jvm" version "1.1.2-2"
|
||||
}
|
||||
|
||||
if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'org.jackhuang.hmcl.Main'
|
||||
}
|
||||
|
||||
def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
|
||||
if (buildnumber == null)
|
||||
buildnumber = System.getenv("BUILD_NUMBER")
|
||||
if (buildnumber == null)
|
||||
buildnumber = "33"
|
||||
|
||||
def versionroot = System.getenv("VERSION_ROOT")
|
||||
if (versionroot == null)
|
||||
versionroot = "2.7.8"
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = versionroot + '.' + buildnumber
|
||||
String bundleName = "Hello Minecraft! Launcher"
|
||||
|
||||
group = mavenGroupId
|
||||
version = mavenVersion
|
||||
|
||||
String mavenArtifactId = name
|
||||
|
||||
task generateSources(type: Sync) {
|
||||
from 'src/main/java'
|
||||
into "$buildDir/generated-src"
|
||||
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [
|
||||
'HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING': mavenVersion
|
||||
])
|
||||
}
|
||||
compileJava.setSource "$buildDir/generated-src"
|
||||
compileJava.dependsOn generateSources
|
||||
|
||||
configurations {
|
||||
coreCompile.extendsFrom compile
|
||||
coreRuntime.extendsFrom runtime
|
||||
}
|
||||
|
||||
configure(install.repositories.mavenInstaller) {
|
||||
pom.project {
|
||||
groupId = mavenGroupId
|
||||
artifactId = mavenArtifactId
|
||||
version = mavenVersion
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":HMCLaF")
|
||||
compile project(":HMCLAPI")
|
||||
compile project(":HMCLCore")
|
||||
compile rootProject.files("lib/JFoenix.jar")
|
||||
}
|
||||
|
||||
retrolambda {
|
||||
javaVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
jar {
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
|
||||
manifest {
|
||||
attributes 'Created-By' : 'Copyright(c) 2013-2017 huangyuhui.',
|
||||
'Main-Class' : mainClass
|
||||
}
|
||||
|
||||
doLast {
|
||||
new File("build/signed").mkdirs()
|
||||
ant.signjar(signedjar: archivePath, jar: archivePath,
|
||||
keystore: "HMCL.keystore", storepass: "123456",
|
||||
alias: "HMCL")
|
||||
|
||||
def messageDigest = MessageDigest.getInstance("SHA1")
|
||||
archivePath.eachByte 1024 * 1024, { byte[] buf, int bytesRead ->
|
||||
messageDigest.update(buf, 0, bytesRead);
|
||||
}
|
||||
def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft(40, '0')
|
||||
def fileEx = new File(project.buildDir, "libs/" + archivePath.getName() + ".sha1")
|
||||
if (!fileEx.exists()) fileEx.createNewFile()
|
||||
fileEx.append sha1Hex
|
||||
}
|
||||
}
|
||||
|
||||
launch4j {
|
||||
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||
jreMinVersion = '1.7.0'
|
||||
|
||||
mainClassName = mainClass
|
||||
icon = new File(project.buildDir, '../icon.ico').absolutePath
|
||||
version = mavenVersion
|
||||
downloadUrl = 'http://java.com/download'
|
||||
copyright = "Copyright(c) 2013-2017 huangyuhui."
|
||||
|
||||
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
|
||||
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
|
||||
messagesJreVersionError = 'This application requires a Java Runtime Environment installation, or the runtime is corrupted.\n\u6ca1\u6709\u627e\u5230\u004a\u0061\u0076\u0061\u8fd0\u884c\u65f6\uff0c\u8bf7\u4e0d\u8981\u4f7f\u7528\u7eff\u8272\u004a\u0061\u0076\u0061\uff0c\u8bf7\u4f7f\u7528\u5b89\u88c5\u7248\u7684\u004a\u0061\u0076\u0061\uff0c\u70b9\u51fb\u786e\u5b9a\u8fdb\u5165\u004a\u0061\u0076\u0061\u5b89\u88c5\u9875\u9762\u3002'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'icon.icns'
|
||||
}
|
||||
}
|
||||
|
||||
task makeExecutable(dependsOn: jar) doLast {
|
||||
ext {
|
||||
jar.classifier = ''
|
||||
makeExecutableinjar = jar.archivePath
|
||||
jar.classifier = ''
|
||||
makeExecutableoutjar = jar.archivePath
|
||||
jar.classifier = ''
|
||||
}
|
||||
def loc = new File(project.buildDir, "libs/" + makeExecutableoutjar.getName().substring(0, makeExecutableoutjar.getName().length()-4)+".exe")
|
||||
def fos = new FileOutputStream(loc)
|
||||
def is = new FileInputStream(new File(project.buildDir, '../HMCLauncher.exe'))
|
||||
int read
|
||||
def bytes = new byte[8192]
|
||||
while((read = is.read(bytes)) != -1)
|
||||
fos.write(bytes, 0, read);
|
||||
is.close()
|
||||
is = new FileInputStream(makeExecutableinjar)
|
||||
while((read = is.read(bytes)) != -1)
|
||||
fos.write(bytes, 0, read);
|
||||
is.close()
|
||||
fos.close()
|
||||
|
||||
}
|
||||
|
||||
task makePackGZ(dependsOn: jar) doLast {
|
||||
ext {
|
||||
jar.classifier = ''
|
||||
makeExecutableinjar = jar.archivePath
|
||||
jar.classifier = ''
|
||||
makeExecutableoutjar = jar.archivePath
|
||||
jar.classifier = ''
|
||||
}
|
||||
def loc = new File(project.buildDir, "libs/" + makeExecutableoutjar.getName().substring(0, makeExecutableoutjar.getName().length()-4)+".pack.gz")
|
||||
def os = new GZIPOutputStream(new FileOutputStream(loc))
|
||||
Pack200.newPacker().pack new JarFile(makeExecutableinjar), os
|
||||
os.close()
|
||||
|
||||
def messageDigest = MessageDigest.getInstance("SHA1")
|
||||
loc.eachByte 1024 * 1024, { byte[] buf, int bytesRead ->
|
||||
messageDigest.update(buf, 0, bytesRead);
|
||||
}
|
||||
def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft(40, '0')
|
||||
def fileEx = new File(project.buildDir, "libs/" + makeExecutableoutjar.getName().substring(0, makeExecutableoutjar.getName().length()-4)+".pack.gz.sha1")
|
||||
if (!fileEx.exists()) fileEx.createNewFile()
|
||||
fileEx.append sha1Hex
|
||||
}
|
||||
|
||||
task macAppCompressed(type: Zip, dependsOn: createApp) doLast {
|
||||
archiveName "HMCL-$mavenVersion-MacOSApp.zip"
|
||||
include '**'
|
||||
destinationDir file("$buildDir/libs/")
|
||||
from "$buildDir/macApp"
|
||||
}
|
||||
|
||||
macAppBundle {
|
||||
mainClassName = mainClass
|
||||
icon = "src/main/icon.icns"
|
||||
javaProperties.put("apple.laf.useScreenMenuBar", "true")
|
||||
}
|
||||
|
||||
build.dependsOn makeExecutable
|
||||
build.dependsOn makePackGZ
|
||||
build.dependsOn macAppCompressed
|
||||
BIN
HMCL/icon.ico
BIN
HMCL/icon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
@@ -1,251 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.RepaintManager;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.ILogger;
|
||||
import org.jackhuang.hmcl.api.PluginManager;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.core.MCUtils;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.ui.LogWindow;
|
||||
import org.jackhuang.hmcl.ui.MainFrame;
|
||||
import org.jackhuang.hmcl.util.CrashReporter;
|
||||
import org.jackhuang.hmcl.util.DefaultPlugin;
|
||||
import org.jackhuang.hmcl.util.MathUtils;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.lang.SupportedLocales;
|
||||
import org.jackhuang.hmcl.util.log.Configuration;
|
||||
import org.jackhuang.hmcl.util.log.appender.ConsoleAppender;
|
||||
import org.jackhuang.hmcl.util.log.layout.DefaultLayout;
|
||||
import org.jackhuang.hmcl.util.ui.MyRepaintManager;
|
||||
import org.jackhuang.hmcl.util.upgrade.IUpgrader;
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Main {
|
||||
|
||||
private static final X509TrustManager XTM = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
};
|
||||
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
||||
|
||||
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
||||
public static final String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@";
|
||||
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
||||
|
||||
/**
|
||||
* Make the main window title.
|
||||
*
|
||||
* @return the MainWindow title.
|
||||
*/
|
||||
public static String makeTitle() {
|
||||
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
||||
}
|
||||
|
||||
public static String shortTitle() {
|
||||
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
||||
}
|
||||
|
||||
public static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
{
|
||||
try {
|
||||
File file = new File("hmcl.log").getAbsoluteFile();
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
LOGGER.log(Level.WARNING, "Failed to create log file {0}", file);
|
||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
||||
}
|
||||
|
||||
org.jackhuang.hmcl.util.log.logger.Logger logger = new org.jackhuang.hmcl.util.log.logger.Logger("HMCL");
|
||||
HMCLog.LOGGER = new ILogger() {
|
||||
@Override
|
||||
public void log(String msg) {
|
||||
logger.info(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg) {
|
||||
logger.warn(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable t) {
|
||||
logger.warn(msg, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(String msg) {
|
||||
logger.error(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(String msg, Throwable t) {
|
||||
logger.error(msg, t);
|
||||
}
|
||||
};
|
||||
|
||||
HMCLApi.HMCL_VERSION = VersionNumber.check(LAUNCHER_VERSION);
|
||||
|
||||
PluginManager.getPlugin(DefaultPlugin.class);
|
||||
for (String s : args)
|
||||
if (s.startsWith("--plugin=")) {
|
||||
String c = s.substring("--plugin=".length());
|
||||
try {
|
||||
PluginManager.getPlugin(Class.forName(c));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
HMCLog.warn("Class: " + c + " not found, please add your plugin jar to class path.", ex);
|
||||
}
|
||||
} else if (s.startsWith("--help")) {
|
||||
System.out.println("HMCL command line help");
|
||||
System.out.println("--noupdate: this arg will prevent HMCL from initializing the newest app version in %appdata%/.hmcl");
|
||||
System.out.println("--plugin=<your plugin class>: this arg will allow a new plugin to be loaded, please keep your jar in system class path and this class extends IPlugin.");
|
||||
return;
|
||||
}
|
||||
PluginManager.loadPlugins();
|
||||
|
||||
IUpgrader.NOW_UPGRADER.parseArguments(HMCLApi.HMCL_VERSION, args);
|
||||
|
||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||
System.setProperty("swing.aatext", "true");
|
||||
System.setProperty("sun.java2d.noddraw", "true");
|
||||
System.setProperty("sun.java2d.dpiaware", "false");
|
||||
System.setProperty("https.protocols", "SSLv3,TLSv1");
|
||||
|
||||
try {
|
||||
SSLContext c = SSLContext.getInstance("SSL");
|
||||
c.init(null, new X509TrustManager[] { XTM }, new java.security.SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(c.getSocketFactory());
|
||||
} catch (GeneralSecurityException ignore) {
|
||||
}
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
||||
|
||||
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
String s = Settings.getInstance().getLocalization();
|
||||
for (SupportedLocales sl : SupportedLocales.values())
|
||||
if (sl.name().equals(s)) {
|
||||
SupportedLocales.setNowLocale(sl);
|
||||
Locale.setDefault(sl.self);
|
||||
JOptionPane.setDefaultLocale(sl.self);
|
||||
}
|
||||
|
||||
if (System.getProperty("java.vm.name").contains("Open")) // OpenJDK
|
||||
MessageBox.showLocalized("ui.message.open_jdk");
|
||||
|
||||
try {
|
||||
BeautyEyeLNFHelper.launchBeautyEyeLNF();
|
||||
RepaintManager.setCurrentManager(new MyRepaintManager());
|
||||
} catch (Exception ex) {
|
||||
HMCLog.warn("Failed to set look and feel...", ex);
|
||||
}
|
||||
|
||||
LogWindow.INSTANCE.clean();
|
||||
|
||||
Settings.UPDATE_CHECKER.upgrade.register(IUpgrader.NOW_UPGRADER);
|
||||
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
||||
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
||||
HMCLog.log("Initializing customized proxy");
|
||||
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
||||
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword()))
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
unpackDefaultLog4jConfiguration();
|
||||
} catch(IOException e) {
|
||||
HMCLog.err("Failed to unpack log4j.xml, log window will not work well.", e);
|
||||
}
|
||||
|
||||
MainFrame.showMainFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeUpdate() {
|
||||
MainFrame.INSTANCE.invokeUpdate();
|
||||
}
|
||||
|
||||
public static final File LOG4J_FILE = new File(MCUtils.getWorkingDirectory("hmcl"), "log4j.xml");
|
||||
|
||||
public static void unpackDefaultLog4jConfiguration() throws IOException {
|
||||
LOG4J_FILE.getParentFile().mkdirs();
|
||||
if (LOG4J_FILE.exists()) return;
|
||||
LOG4J_FILE.createNewFile();
|
||||
try (InputStream is = Main.class.getResourceAsStream("/org/jackhuang/hmcl/log4j.xml");
|
||||
FileOutputStream fos = new FileOutputStream(LOG4J_FILE)) {
|
||||
int b;
|
||||
while ((b = is.read()) != -1)
|
||||
fos.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public static ImageIcon getIcon(String path) {
|
||||
try {
|
||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hmcl/" + path));
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to load icon", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.config;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
|
||||
/**
|
||||
* This event gets fired when the selected profile changed.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Settings}
|
||||
* @param Profile the new profile.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ProfileChangedEvent extends SimpleEvent<Profile> {
|
||||
|
||||
public ProfileChangedEvent(Object source, Profile value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.config;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* This event gets fired when loading profiles.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Settings}
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ProfileLoadingEvent extends EventObject {
|
||||
|
||||
public ProfileLoadingEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.setting;
|
||||
|
||||
import org.jackhuang.hmcl.core.download.DownloadType;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hmcl.core.auth.AbstractAuthenticator;
|
||||
import org.jackhuang.hmcl.laf.LAFTheme;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.config.AuthenticatorChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.config.DownloadTypeChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.config.ThemeChangedEvent;
|
||||
import org.jackhuang.hmcl.core.MCUtils;
|
||||
import org.jackhuang.hmcl.util.sys.JdkVersion;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.api.ui.Theme;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Config implements Cloneable {
|
||||
|
||||
@SerializedName("last")
|
||||
private String last;
|
||||
@SerializedName("bgpath")
|
||||
private String bgpath;
|
||||
@SerializedName("commonpath")
|
||||
private String commonpath;
|
||||
@SerializedName("clientToken")
|
||||
private final String clientToken;
|
||||
@SerializedName("proxyHost")
|
||||
private String proxyHost;
|
||||
@SerializedName("proxyPort")
|
||||
private String proxyPort;
|
||||
@SerializedName("proxyUserName")
|
||||
private String proxyUserName;
|
||||
@SerializedName("proxyPassword")
|
||||
private String proxyPassword;
|
||||
@SerializedName("enableShadow")
|
||||
private boolean enableShadow;
|
||||
@SerializedName("enableBlur")
|
||||
private boolean enableBlur;
|
||||
@SerializedName("enableAnimation")
|
||||
private boolean enableAnimation;
|
||||
@SerializedName("decorated")
|
||||
private boolean decorated;
|
||||
@SerializedName("theme")
|
||||
private String theme;
|
||||
@SerializedName("java")
|
||||
private List<JdkVersion> java;
|
||||
@SerializedName("localization")
|
||||
private String localization;
|
||||
@SerializedName("logintype")
|
||||
private int logintype;
|
||||
@SerializedName("downloadtype")
|
||||
private int downloadtype;
|
||||
@SerializedName("configurations")
|
||||
private TreeMap<String, Profile> configurations;
|
||||
@SerializedName("auth")
|
||||
private Map<String, Map> auth;
|
||||
@SerializedName("fontFamily")
|
||||
private String fontFamily;
|
||||
@SerializedName("fontSize")
|
||||
private int fontSize;
|
||||
@SerializedName("logLines")
|
||||
private int logLines;
|
||||
|
||||
public Config() {
|
||||
clientToken = UUID.randomUUID().toString();
|
||||
logintype = downloadtype = 0;
|
||||
logLines = 100;
|
||||
enableAnimation = enableBlur = true;
|
||||
if (OS.os() == OS.WINDOWS)
|
||||
enableShadow = true;
|
||||
theme = LAFTheme.BLUE.id;
|
||||
decorated = OS.os() == OS.LINUX;
|
||||
auth = new HashMap<>();
|
||||
Font font = Font.decode("Consolas");
|
||||
if (font == null)
|
||||
font = Font.decode("Monospace");
|
||||
if (font != null)
|
||||
fontFamily = font.getFamily();
|
||||
fontSize = 12;
|
||||
commonpath = MCUtils.getLocation().getPath();
|
||||
}
|
||||
|
||||
public List<JdkVersion> getJava() {
|
||||
return java == null ? java = new ArrayList<>() : java;
|
||||
}
|
||||
|
||||
public Theme getTheme() {
|
||||
if (!Theme.THEMES.containsKey(theme))
|
||||
theme = LAFTheme.BLUE.id;
|
||||
return Theme.THEMES.get(theme);
|
||||
}
|
||||
|
||||
public void setTheme(String theme) {
|
||||
this.theme = theme;
|
||||
HMCLApi.EVENT_BUS.fireChannel(new ThemeChangedEvent(this, getTheme()));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isDecorated() {
|
||||
return decorated;
|
||||
}
|
||||
|
||||
public void setDecorated(boolean decorated) {
|
||||
this.decorated = decorated;
|
||||
}
|
||||
|
||||
public boolean isEnableShadow() {
|
||||
return enableShadow && OS.os() == OS.WINDOWS;
|
||||
}
|
||||
|
||||
public void setEnableShadow(boolean enableShadow) {
|
||||
this.enableShadow = enableShadow;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isEnableAnimation() {
|
||||
return enableAnimation;
|
||||
}
|
||||
|
||||
public void setEnableAnimation(boolean enableAnimation) {
|
||||
this.enableAnimation = enableAnimation;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isEnableBlur() {
|
||||
return enableBlur;
|
||||
}
|
||||
|
||||
public void setEnableBlur(boolean enableBlur) {
|
||||
this.enableBlur = enableBlur;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Last selected profile name.
|
||||
*/
|
||||
public String getLast() {
|
||||
if (last == null)
|
||||
last = Settings.DEFAULT_PROFILE;
|
||||
return last;
|
||||
}
|
||||
|
||||
public void setLast(String last) {
|
||||
this.last = last;
|
||||
Settings.onProfileChanged();
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getBgpath() {
|
||||
return bgpath;
|
||||
}
|
||||
|
||||
public void setBgpath(String bgpath) {
|
||||
this.bgpath = bgpath;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getCommonpath() {
|
||||
return commonpath;
|
||||
}
|
||||
|
||||
public void setCommonpath(String commonpath) {
|
||||
this.commonpath = commonpath;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public IAuthenticator getAuthenticator() {
|
||||
return AbstractAuthenticator.LOGINS.get(getLoginType());
|
||||
}
|
||||
|
||||
public int getLoginType() {
|
||||
if (logintype < 0 || logintype >= AbstractAuthenticator.LOGINS.size())
|
||||
logintype = 0;
|
||||
return logintype;
|
||||
}
|
||||
|
||||
public void setLoginType(int logintype) {
|
||||
if (logintype < 0 || logintype >= AbstractAuthenticator.LOGINS.size())
|
||||
return;
|
||||
this.logintype = logintype;
|
||||
HMCLApi.EVENT_BUS.fireChannel(new AuthenticatorChangedEvent(this, AbstractAuthenticator.LOGINS.get(logintype)));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getDownloadType() {
|
||||
return downloadtype;
|
||||
}
|
||||
|
||||
public void setDownloadType(int downloadtype) {
|
||||
this.downloadtype = downloadtype;
|
||||
HMCLApi.EVENT_BUS.fireChannel(new DownloadTypeChangedEvent(this, getDownloadSource().name()));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public TreeMap<String, Profile> getConfigurations() {
|
||||
if (configurations == null)
|
||||
configurations = new TreeMap<>();
|
||||
if (configurations.isEmpty()) {
|
||||
Profile profile = new Profile();
|
||||
configurations.put(profile.getName(), profile);
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
|
||||
public Map getAuthenticatorConfig(String authId) {
|
||||
return auth.get(authId);
|
||||
}
|
||||
|
||||
public void setAuthenticatorConfig(String authId, Map map) {
|
||||
auth.put(authId, map);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public DownloadType getDownloadSource() {
|
||||
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
||||
downloadtype = 0;
|
||||
Settings.save();
|
||||
}
|
||||
return DownloadType.values()[downloadtype];
|
||||
}
|
||||
|
||||
public String getProxyHost() {
|
||||
return proxyHost == null ? "" : proxyHost;
|
||||
}
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
this.proxyHost = proxyHost;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyPort() {
|
||||
return proxyPort == null ? "" : proxyPort;
|
||||
}
|
||||
|
||||
public void setProxyPort(String proxyPort) {
|
||||
this.proxyPort = proxyPort;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyUserName() {
|
||||
return proxyUserName == null ? "" : proxyUserName;
|
||||
}
|
||||
|
||||
public void setProxyUserName(String proxyUserName) {
|
||||
this.proxyUserName = proxyUserName;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyPassword() {
|
||||
return proxyPassword == null ? "" : proxyPassword;
|
||||
}
|
||||
|
||||
public void setProxyPassword(String proxyPassword) {
|
||||
this.proxyPassword = proxyPassword;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getFontSize() {
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
public void setFontSize(int fontSize) {
|
||||
this.fontSize = fontSize;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public Font getConsoleFont() {
|
||||
return Font.decode(fontFamily + "-" + fontSize);
|
||||
}
|
||||
|
||||
public String getFontFamily() {
|
||||
return Font.decode(fontFamily).getFamily();
|
||||
}
|
||||
|
||||
public void setFontFamily(String fontFamily) {
|
||||
this.fontFamily = Font.decode(fontFamily).getFamily(); // avoid invalid font family
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getLocalization() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
public void setLocalization(String localization) {
|
||||
this.localization = localization;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getLogLines() {
|
||||
if (logLines == 100 || logLines == 1000 || logLines == 5000)
|
||||
return logLines;
|
||||
else
|
||||
return logLines = 100;
|
||||
}
|
||||
|
||||
public void setLogLines(int logLines) {
|
||||
this.logLines = logLines;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.setting;
|
||||
|
||||
import org.jackhuang.hmcl.core.service.IProfile;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hmcl.util.HMCLGameLauncher;
|
||||
import org.jackhuang.hmcl.util.HMCLMinecraftService;
|
||||
import java.io.File;
|
||||
import org.jackhuang.hmcl.core.MCUtils;
|
||||
import org.jackhuang.hmcl.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.api.event.EventHandler;
|
||||
import org.jackhuang.hmcl.api.event.PropertyChangedEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Profile implements IProfile {
|
||||
|
||||
@SerializedName("selectedMinecraftVersion")
|
||||
private String selectedVersion = "";
|
||||
@SerializedName("gameDir")
|
||||
private String gameDir;
|
||||
@SerializedName("noCommon")
|
||||
private boolean noCommon;
|
||||
@SerializedName("global")
|
||||
private VersionSetting global;
|
||||
|
||||
private transient String name;
|
||||
private transient HMCLMinecraftService service = new HMCLMinecraftService(this);
|
||||
private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this);
|
||||
public transient final EventHandler<PropertyChangedEvent<String>> propertyChanged = new EventHandler<>();
|
||||
|
||||
public Profile() {
|
||||
this("Default");
|
||||
}
|
||||
|
||||
public Profile(String name) {
|
||||
this(name, ".minecraft");
|
||||
}
|
||||
|
||||
public Profile(String name, String gameDir) {
|
||||
this.name = name;
|
||||
this.gameDir = gameDir;
|
||||
this.global = new VersionSetting();
|
||||
}
|
||||
|
||||
public Profile(String name, Profile v) {
|
||||
this();
|
||||
if (v == null)
|
||||
return;
|
||||
this.name = name;
|
||||
gameDir = v.gameDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HMCLMinecraftService service() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public HMCLGameLauncher launcher() {
|
||||
return launcher;
|
||||
}
|
||||
|
||||
public VersionSetting getSelectedVersionSetting() {
|
||||
return getVersionSetting(getSelectedVersion());
|
||||
}
|
||||
|
||||
public VersionSetting getVersionSetting(String id) {
|
||||
VersionSetting vs = service().getVersionSetting(id);
|
||||
if (vs == null || vs.isUsesGlobal()) {
|
||||
global.isGlobal = true;
|
||||
global.id = id;
|
||||
return global;
|
||||
} else
|
||||
return vs;
|
||||
}
|
||||
|
||||
public boolean isVersionSettingGlobe(String id) {
|
||||
VersionSetting vs = service().getVersionSetting(id);
|
||||
return vs == null || vs.isUsesGlobal();
|
||||
}
|
||||
|
||||
public void makeVersionSettingSpecial(String id) {
|
||||
VersionSetting vs = service().getVersionSetting(id);
|
||||
if (vs == null) {
|
||||
service().createVersionSetting(id);
|
||||
vs = service().getVersionSetting(id);
|
||||
if (vs == null)
|
||||
return;
|
||||
vs.setUsesGlobal(false);
|
||||
} else
|
||||
vs.setUsesGlobal(false);
|
||||
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedVersion", selectedVersion, selectedVersion));
|
||||
}
|
||||
|
||||
public void makeVersionSettingGlobal(String id) {
|
||||
HMCLMinecraftService s = (HMCLMinecraftService) service();
|
||||
VersionSetting vs = s.getVersionSetting(id);
|
||||
if (vs == null)
|
||||
return;
|
||||
vs.setUsesGlobal(true);
|
||||
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedVersion", selectedVersion, selectedVersion));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedVersion() {
|
||||
String v = selectedVersion;
|
||||
if (StrUtils.isBlank(v) || service().version().getVersionById(v) == null || service().version().getVersionById(v).hidden) {
|
||||
MinecraftVersion mv = service().version().getOneVersion(t -> !t.hidden);
|
||||
if (mv != null)
|
||||
v = mv.id;
|
||||
if (StrUtils.isNotBlank(v))
|
||||
setSelectedVersion(v);
|
||||
}
|
||||
return StrUtils.isBlank(v) ? null : v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedVersion(String newVersion) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "selectedVersion", this.selectedVersion, newVersion);
|
||||
this.selectedVersion = newVersion;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getGameDir() {
|
||||
if (StrUtils.isBlank(gameDir))
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
return new File(gameDir.replace('\\', '/'));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameDir(File gameDir) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "gameDir", this.gameDir, gameDir);
|
||||
this.gameDir = gameDir.getPath();
|
||||
service().version().refreshVersions();
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public boolean isNoCommon() {
|
||||
return noCommon;
|
||||
}
|
||||
|
||||
public void setNoCommon(boolean noCommon) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "noCommon", this.noCommon, noCommon);
|
||||
this.noCommon = noCommon;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "name", this.name, name);
|
||||
this.name = name;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelected() {
|
||||
service().version().refreshVersions();
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.setting;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.core.MCUtils;
|
||||
import org.jackhuang.hmcl.core.download.DownloadType;
|
||||
import org.jackhuang.hmcl.util.CollectionUtils;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.config.ProfileChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.config.ProfileLoadingEvent;
|
||||
import org.jackhuang.hmcl.laf.utils.AnimationController;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.UpdateChecker;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Settings {
|
||||
|
||||
public static final String DEFAULT_PROFILE = "Default";
|
||||
public static final String HOME_PROFILE = "Home";
|
||||
|
||||
public static final File SETTINGS_FILE = new File("hmcl.json").getAbsoluteFile();
|
||||
|
||||
private static final Config SETTINGS;
|
||||
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(HMCLApi.HMCL_VERSION, "hmcl");
|
||||
|
||||
public static Config getInstance() {
|
||||
return SETTINGS;
|
||||
}
|
||||
|
||||
static {
|
||||
SETTINGS = initSettings();
|
||||
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource().name());
|
||||
AnimationController.ENABLE_ANIMATION = SETTINGS.isEnableAnimation();
|
||||
if (!getProfiles().containsKey(DEFAULT_PROFILE))
|
||||
getProfiles().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE));
|
||||
|
||||
for (Map.Entry<String, Profile> entry : getProfiles().entrySet()) {
|
||||
Profile e = entry.getValue();
|
||||
e.setName(entry.getKey());
|
||||
e.propertyChanged.register(Settings::save);
|
||||
}
|
||||
}
|
||||
|
||||
private static Config initSettings() {
|
||||
Config c = new Config();
|
||||
if (SETTINGS_FILE.exists())
|
||||
try {
|
||||
String str = FileUtils.read(SETTINGS_FILE, IOUtils.DEFAULT_CHARSET);
|
||||
if (str == null || str.trim().equals(""))
|
||||
HMCLog.log("Settings file is empty, use the default settings.");
|
||||
else {
|
||||
Config d = C.GSON.fromJson(str, Config.class);
|
||||
if (d != null)
|
||||
c = d;
|
||||
}
|
||||
HMCLog.log("Initialized settings.");
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Something happened wrongly when load settings.", e);
|
||||
}
|
||||
else {
|
||||
HMCLog.log("No settings file here, may be first loading.");
|
||||
if (!c.getConfigurations().containsKey(HOME_PROFILE))
|
||||
c.getConfigurations().put(HOME_PROFILE, new Profile(HOME_PROFILE, MCUtils.getLocation().getPath()));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
FileUtils.write(SETTINGS_FILE, C.GSON.toJson(SETTINGS), IOUtils.DEFAULT_CHARSET);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to save config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Profile getLastProfile() {
|
||||
if (!hasProfile(getInstance().getLast()))
|
||||
getInstance().setLast(DEFAULT_PROFILE);
|
||||
return getProfile(getInstance().getLast());
|
||||
}
|
||||
|
||||
public static Profile getProfile(String name) {
|
||||
if (name == null)
|
||||
name = DEFAULT_PROFILE;
|
||||
Profile p = getProfiles().get(name);
|
||||
if (p == null)
|
||||
if (getProfiles().containsKey(DEFAULT_PROFILE))
|
||||
p = getProfiles().get(DEFAULT_PROFILE);
|
||||
else
|
||||
getProfiles().put(DEFAULT_PROFILE, p = new Profile());
|
||||
return p;
|
||||
}
|
||||
|
||||
public static boolean hasProfile(String name) {
|
||||
if (name == null)
|
||||
name = DEFAULT_PROFILE;
|
||||
return getProfiles().containsKey(name);
|
||||
}
|
||||
|
||||
public static Map<String, Profile> getProfiles() {
|
||||
return SETTINGS.getConfigurations();
|
||||
}
|
||||
|
||||
public static Collection<Profile> getProfilesFiltered() {
|
||||
return CollectionUtils.filter(getProfiles().values(), t -> t != null && t.getName() != null);
|
||||
}
|
||||
|
||||
public static boolean putProfile(Profile ver) {
|
||||
if (ver == null || ver.getName() == null || getProfiles().containsKey(ver.getName()))
|
||||
return false;
|
||||
getProfiles().put(ver.getName(), ver);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean delProfile(Profile ver) {
|
||||
return delProfile(ver.getName());
|
||||
}
|
||||
|
||||
public static boolean delProfile(String ver) {
|
||||
if (DEFAULT_PROFILE.equals(ver)) {
|
||||
MessageBox.show(C.i18n("settings.cannot_remove_default_config"));
|
||||
return false;
|
||||
}
|
||||
boolean notify = false;
|
||||
if (getLastProfile().getName().equals(ver))
|
||||
notify = true;
|
||||
boolean flag = getProfiles().remove(ver) != null;
|
||||
if (notify && flag)
|
||||
onProfileChanged();
|
||||
return flag;
|
||||
}
|
||||
|
||||
static void onProfileChanged() {
|
||||
Profile p = getLastProfile();
|
||||
if (p == null)
|
||||
throw new Error("No profiles here, it should not happen");
|
||||
HMCLApi.EVENT_BUS.fireChannel(new ProfileChangedEvent(SETTINGS, p));
|
||||
p.onSelected();
|
||||
}
|
||||
|
||||
public static void onProfileLoading() {
|
||||
HMCLApi.EVENT_BUS.fireChannel(new ProfileLoadingEvent(SETTINGS));
|
||||
onProfileChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.setting;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.io.File;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.util.LauncherVisibility;
|
||||
import org.jackhuang.hmcl.api.game.LaunchOptions;
|
||||
import org.jackhuang.hmcl.api.game.GameDirType;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.api.event.EventHandler;
|
||||
import org.jackhuang.hmcl.api.event.PropertyChangedEvent;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.sys.Java;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class VersionSetting {
|
||||
|
||||
public transient String id;
|
||||
public transient boolean isGlobal = false;
|
||||
|
||||
@SerializedName("usesGlobal")
|
||||
private boolean usesGlobal;
|
||||
@SerializedName("javaArgs")
|
||||
private String javaArgs;
|
||||
@SerializedName("minecraftArgs")
|
||||
private String minecraftArgs;
|
||||
@SerializedName("maxMemory")
|
||||
private String maxMemory;
|
||||
@SerializedName("permSize")
|
||||
private String permSize;
|
||||
@SerializedName("width")
|
||||
private String width;
|
||||
@SerializedName("height")
|
||||
private String height;
|
||||
@SerializedName("javaDir")
|
||||
private String javaDir;
|
||||
@SerializedName("precalledCommand")
|
||||
private String precalledCommand;
|
||||
@SerializedName("serverIp")
|
||||
private String serverIp;
|
||||
@SerializedName("java")
|
||||
private String java;
|
||||
@SerializedName("wrapper")
|
||||
private String wrapper;
|
||||
@SerializedName("fullscreen")
|
||||
private boolean fullscreen;
|
||||
@SerializedName("noJVMArgs")
|
||||
private boolean noJVMArgs;
|
||||
@SerializedName("notCheckGame")
|
||||
private boolean notCheckGame;
|
||||
|
||||
/**
|
||||
* 0 - Close the launcher when the game starts.<br/>
|
||||
* 1 - Hide the launcher when the game starts.<br/>
|
||||
* 2 - Keep the launcher open.<br/>
|
||||
*/
|
||||
@SerializedName("launcherVisibility")
|
||||
private int launcherVisibility;
|
||||
|
||||
/**
|
||||
* 0 - .minecraft<br/>
|
||||
* 1 - .minecraft/versions/<version>/<br/>
|
||||
*/
|
||||
@SerializedName("gameDirType")
|
||||
private int gameDirType;
|
||||
|
||||
public transient final EventHandler<PropertyChangedEvent> propertyChanged = new EventHandler<>();
|
||||
|
||||
public VersionSetting() {
|
||||
fullscreen = usesGlobal = false;
|
||||
launcherVisibility = 1;
|
||||
gameDirType = 0;
|
||||
javaDir = java = minecraftArgs = serverIp = precalledCommand = wrapper = "";
|
||||
}
|
||||
|
||||
public String getJavaDir() {
|
||||
Java j = getJava();
|
||||
if (j.getHome() == null)
|
||||
return javaDir;
|
||||
else
|
||||
return j.getJava();
|
||||
}
|
||||
|
||||
public String getSettingsJavaDir() {
|
||||
return javaDir;
|
||||
}
|
||||
|
||||
public File getJavaDirFile() {
|
||||
return new File(getJavaDir());
|
||||
}
|
||||
|
||||
public void setJavaDir(String javaDir) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaDir", this.javaDir, javaDir);
|
||||
this.javaDir = javaDir;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public Java getJava() {
|
||||
return Java.JAVA.get(getJavaIndexInAllJavas());
|
||||
}
|
||||
|
||||
public int getJavaIndexInAllJavas() {
|
||||
if (StrUtils.isBlank(java) && StrUtils.isNotBlank(javaDir))
|
||||
java = "Custom";
|
||||
int idx = Java.JAVA.indexOf(new Java(java, null));
|
||||
if (idx == -1) {
|
||||
java = Java.suggestedJava().getName();
|
||||
idx = 0;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
public void setJava(Java java) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "java", this.java, java);
|
||||
if (java == null)
|
||||
this.java = Java.JAVA.get(0).getName();
|
||||
else {
|
||||
int idx = Java.JAVA.indexOf(java);
|
||||
if (idx == -1)
|
||||
return;
|
||||
this.java = java.getName();
|
||||
}
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getJavaArgs() {
|
||||
if (StrUtils.isBlank(javaArgs))
|
||||
return "";
|
||||
return javaArgs;
|
||||
}
|
||||
|
||||
public void setJavaArgs(String javaArgs) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaArgs", this.javaArgs, javaArgs);
|
||||
this.javaArgs = javaArgs;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getMaxMemory() {
|
||||
if (StrUtils.isBlank(maxMemory))
|
||||
return String.valueOf(OS.getSuggestedMemorySize());
|
||||
return maxMemory;
|
||||
}
|
||||
|
||||
public void setMaxMemory(String maxMemory) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "maxMemory", this.maxMemory, maxMemory);
|
||||
this.maxMemory = maxMemory;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
if (StrUtils.isBlank(width))
|
||||
return "854";
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(String width) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "width", this.width, width);
|
||||
this.width = width;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
if (StrUtils.isBlank(height))
|
||||
return "480";
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(String height) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "height", this.height, height);
|
||||
this.height = height;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
|
||||
public void setFullscreen(boolean fullscreen) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "fullscreen", this.fullscreen, fullscreen);
|
||||
this.fullscreen = fullscreen;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public LauncherVisibility getLauncherVisibility() {
|
||||
return LauncherVisibility.values()[launcherVisibility];
|
||||
}
|
||||
|
||||
public void setLauncherVisibility(LauncherVisibility launcherVisibility) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "launcherVisibility", this.launcherVisibility, launcherVisibility);
|
||||
this.launcherVisibility = launcherVisibility.ordinal();
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public GameDirType getGameDirType() {
|
||||
if (gameDirType < 0 || gameDirType > 1)
|
||||
setGameDirType(GameDirType.ROOT_FOLDER);
|
||||
return GameDirType.values()[gameDirType];
|
||||
}
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "gameDirType", this.gameDirType, gameDirType);
|
||||
this.gameDirType = gameDirType.ordinal();
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getPermSize() {
|
||||
return permSize;
|
||||
}
|
||||
|
||||
public void setPermSize(String permSize) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "permSize", this.permSize, permSize);
|
||||
this.permSize = permSize;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public boolean isNoJVMArgs() {
|
||||
return noJVMArgs;
|
||||
}
|
||||
|
||||
public void setNoJVMArgs(boolean noJVMArgs) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "noJVMArgs", this.noJVMArgs, noJVMArgs);
|
||||
this.noJVMArgs = noJVMArgs;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getMinecraftArgs() {
|
||||
return minecraftArgs;
|
||||
}
|
||||
|
||||
public void setMinecraftArgs(String minecraftArgs) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "minecraftArgs", this.minecraftArgs, minecraftArgs);
|
||||
this.minecraftArgs = minecraftArgs;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getPrecalledCommand() {
|
||||
return precalledCommand;
|
||||
}
|
||||
|
||||
public void setPrecalledCommand(String precalledCommand) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "precalledCommand", this.precalledCommand, precalledCommand);
|
||||
this.precalledCommand = precalledCommand;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public void setWrapper(String wrapper) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "wrapper", this.wrapper, wrapper);
|
||||
this.wrapper = wrapper;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
|
||||
public void setServerIp(String serverIp) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "serverIp", this.serverIp, serverIp);
|
||||
this.serverIp = serverIp;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public boolean isNotCheckGame() {
|
||||
return notCheckGame;
|
||||
}
|
||||
|
||||
public void setNotCheckGame(boolean notCheckGame) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "notCheckGame", this.notCheckGame, notCheckGame);
|
||||
this.notCheckGame = notCheckGame;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public boolean isUsesGlobal() {
|
||||
return usesGlobal;
|
||||
}
|
||||
|
||||
public void setUsesGlobal(boolean usesGlobal) {
|
||||
PropertyChangedEvent event = new PropertyChangedEvent(this, "usesGlobal", this.usesGlobal, usesGlobal);
|
||||
this.usesGlobal = usesGlobal;
|
||||
propertyChanged.fire(event);
|
||||
}
|
||||
|
||||
public LaunchOptions createLaunchOptions(File gameDir) {
|
||||
LaunchOptions x = new LaunchOptions();
|
||||
x.setFullscreen(isFullscreen());
|
||||
x.setWrapper(getWrapper());
|
||||
x.setGameDir(gameDir);
|
||||
x.setHeight(getHeight());
|
||||
x.setJavaArgs(getJavaArgs());
|
||||
x.setLaunchVersion(id);
|
||||
x.setMaxMemory(getMaxMemory());
|
||||
x.setMinecraftArgs(getMinecraftArgs());
|
||||
x.setName(Main.shortTitle());
|
||||
x.setType(Main.shortTitle());
|
||||
x.setVersionName(Main.shortTitle());
|
||||
x.setNoJVMArgs(isNoJVMArgs());
|
||||
x.setNotCheckGame(isNotCheckGame());
|
||||
x.setPermSize(getPermSize());
|
||||
x.setPrecalledCommand(getPrecalledCommand());
|
||||
x.setProxyHost(Settings.getInstance().getProxyHost());
|
||||
x.setProxyPort(Settings.getInstance().getProxyPort());
|
||||
x.setProxyUser(Settings.getInstance().getProxyUserName());
|
||||
x.setProxyPass(Settings.getInstance().getProxyPassword());
|
||||
x.setServerIp(getServerIp());
|
||||
x.setWidth(getWidth());
|
||||
|
||||
String str = getJavaDir();
|
||||
if (!getJavaDirFile().exists()) {
|
||||
HMCLog.err(C.i18n("launch.wrong_javadir"));
|
||||
setJava(null);
|
||||
str = getJavaDir();
|
||||
}
|
||||
x.setJavaDir(str);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DraggableFrame extends JFrame
|
||||
implements MouseListener, MouseMotionListener {
|
||||
|
||||
private int dragGripX;
|
||||
private int dragGripY;
|
||||
|
||||
public DraggableFrame() {
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() == 1 && isUndecorated()) {
|
||||
this.dragGripX = e.getX();
|
||||
this.dragGripY = e.getY();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if ((e.getModifiersEx() & 0x400) != 0 && isUndecorated())
|
||||
setLocation(e.getXOnScreen() - this.dragGripX, e.getYOnScreen() - this.dragGripY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" pref="350" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="btnDownload" max="32767" attributes="0"/>
|
||||
<Component id="btnRefreshGameDownloads" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="btnRefreshGameDownloads" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="btnDownload" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane2" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btnDownload">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.download" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDownloadActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="lstDownloads">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.release_time"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class, String.class}, new boolean[]{false, false, false, false})" type="code"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="0"/>
|
||||
</Property>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="btnRefreshGameDownloads">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.refresh" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnRefreshGameDownloadsActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
import org.jackhuang.hmcl.core.download.MinecraftRemoteVersions;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.task.ProgressProviderListener;
|
||||
import org.jackhuang.hmcl.util.task.Task;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class GameDownloadPanel extends Page implements ProgressProviderListener {
|
||||
|
||||
GameSettingsPanel gsp;
|
||||
|
||||
/**
|
||||
* Creates new form GameDownloadPanel
|
||||
*/
|
||||
public GameDownloadPanel(GameSettingsPanel gsp) {
|
||||
initComponents();
|
||||
this.gsp = gsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
btnDownload = new javax.swing.JButton();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
lstDownloads = new javax.swing.JTable();
|
||||
btnRefreshGameDownloads = new javax.swing.JButton();
|
||||
|
||||
btnDownload.setText(C.i18n("ui.button.download")); // NOI18N
|
||||
btnDownload.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnDownloadActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lstDownloads.setModel(SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.release_time"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class, String.class}, new boolean[]{false, false, false, false}));
|
||||
lstDownloads.setToolTipText("");
|
||||
lstDownloads.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
jScrollPane2.setViewportView(lstDownloads);
|
||||
|
||||
btnRefreshGameDownloads.setText(C.i18n("ui.button.refresh")); // NOI18N
|
||||
btnRefreshGameDownloads.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnRefreshGameDownloadsActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(btnDownload, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnRefreshGameDownloads, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(btnRefreshGameDownloads)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnDownload))
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void btnDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadActionPerformed
|
||||
downloadMinecraft();
|
||||
gsp.refreshVersions();
|
||||
}//GEN-LAST:event_btnDownloadActionPerformed
|
||||
|
||||
private void btnRefreshGameDownloadsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshGameDownloadsActionPerformed
|
||||
refreshDownloads();
|
||||
}//GEN-LAST:event_btnRefreshGameDownloadsActionPerformed
|
||||
|
||||
public void refreshDownloads() {
|
||||
if (loading)
|
||||
return;
|
||||
loading = true;
|
||||
DefaultTableModel model = SwingUtils.clearDefaultTable(lstDownloads);
|
||||
model.addRow(new Object[] { C.i18n("message.loading"), "", "" });
|
||||
MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType())
|
||||
.reg((ver) -> model.addRow(new Object[] { ver.id, ver.releaseTime, ver.time,
|
||||
StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type }))
|
||||
.regDone(SwingUtils.invokeLater(() -> {
|
||||
loading = false;
|
||||
lstDownloads.requestFocus();
|
||||
if (model.getRowCount() > 0)
|
||||
model.removeRow(0);
|
||||
})).setProgressProviderListener(this).runAsync();
|
||||
}
|
||||
|
||||
boolean loading = false;
|
||||
|
||||
@Override
|
||||
public void setProgress(Task task, int prog, int max) {
|
||||
DefaultTableModel model = (DefaultTableModel) lstDownloads.getModel();
|
||||
if (model.getRowCount() > 0)
|
||||
model.setValueAt(C.i18n("message.loading") + " " + (prog < 0 ? "???" : Integer.toString(prog * 100 / max) + "%"), 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(Task task, String sta) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressProviderDone(Task task) {
|
||||
}
|
||||
|
||||
void downloadMinecraft() {
|
||||
if (lstDownloads.getSelectedRow() < 0) {
|
||||
MessageBox.show(C.i18n("gamedownload.not_refreshed"));
|
||||
return;
|
||||
}
|
||||
String id = (String) lstDownloads.getModel().getValueAt(lstDownloads.getSelectedRow(), 0);
|
||||
TaskWindow.factory().execute(Settings.getLastProfile().service().download().downloadMinecraft(id));
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnDownload;
|
||||
private javax.swing.JButton btnRefreshGameDownloads;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JTable lstDownloads;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
boolean refreshedDownloads = false;
|
||||
|
||||
@Override
|
||||
public void onSelect(TopTabPage page) {
|
||||
super.onSelect(page);
|
||||
if (!refreshedDownloads) {
|
||||
refreshedDownloads = true;
|
||||
refreshDownloads();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultButtonModel;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HeaderTab extends JLabel
|
||||
implements MouseListener {
|
||||
|
||||
private boolean isActive;
|
||||
private final DefaultButtonModel model;
|
||||
|
||||
public HeaderTab(String text) {
|
||||
super(text);
|
||||
|
||||
this.model = new DefaultButtonModel();
|
||||
setIsActive(false);
|
||||
|
||||
setBorder(BorderFactory.createEmptyBorder(6, 18, 7, 18));
|
||||
addMouseListener(this);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.isActive;
|
||||
}
|
||||
|
||||
public final void setIsActive(boolean isActive) {
|
||||
this.isActive = isActive;
|
||||
setOpaque(isActive);
|
||||
|
||||
EventQueue.invokeLater(HeaderTab.this::repaint);
|
||||
}
|
||||
|
||||
public void addActionListener(ActionListener listener) {
|
||||
this.model.addActionListener(listener);
|
||||
}
|
||||
|
||||
public String getActionCommand() {
|
||||
return this.model.getActionCommand();
|
||||
}
|
||||
|
||||
public ActionListener[] getActionListeners() {
|
||||
return this.model.getActionListeners();
|
||||
}
|
||||
|
||||
public void setActionCommand(String command) {
|
||||
this.model.setActionCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (!isEnabled())
|
||||
return;
|
||||
this.model.setPressed(true);
|
||||
this.model.setArmed(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (!isEnabled())
|
||||
return;
|
||||
this.model.setPressed(false);
|
||||
this.model.setArmed(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (!isEnabled())
|
||||
return;
|
||||
this.model.setRollover(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
if (!isEnabled())
|
||||
return;
|
||||
this.model.setRollover(false);
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane12" pref="292" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="btnRefresh" max="32767" attributes="0"/>
|
||||
<Component id="btnInstall" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane12" pref="147" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="btnInstall" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnRefresh" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btnInstall">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.install" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnInstallActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane12">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="lstInstallers">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.mcversion")},
 new Class[]{String.class, String.class}, new boolean[]{false, false})" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
<JTableSelectionModel selectionMode="0"/>
|
||||
</Property>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="btnRefresh">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.refresh" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnRefreshActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import java.util.List;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.core.install.InstallerType;
|
||||
import org.jackhuang.hmcl.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hmcl.util.task.TaskRunnable;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.task.ProgressProviderListener;
|
||||
import org.jackhuang.hmcl.util.task.Task;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class InstallerPanel extends Page implements ProgressProviderListener {
|
||||
|
||||
GameSettingsPanel gsp;
|
||||
|
||||
/**
|
||||
* Creates new form InstallerPanel
|
||||
*
|
||||
* @param gsp To get the minecraft version
|
||||
* @param installerType load which installer
|
||||
*/
|
||||
public InstallerPanel(GameSettingsPanel gsp, InstallerType installerType) {
|
||||
initComponents();
|
||||
|
||||
animationEnabled = Settings.getInstance().isEnableAnimation();
|
||||
|
||||
setOpaque(false);
|
||||
this.gsp = gsp;
|
||||
id = installerType;
|
||||
list = Settings.getInstance().getDownloadSource().getProvider().getInstallerByType(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
btnInstall = new javax.swing.JButton();
|
||||
jScrollPane12 = new javax.swing.JScrollPane();
|
||||
lstInstallers = new javax.swing.JTable();
|
||||
btnRefresh = new javax.swing.JButton();
|
||||
|
||||
btnInstall.setText(C.i18n("ui.button.install")); // NOI18N
|
||||
btnInstall.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnInstallActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lstInstallers.setModel(SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.mcversion")},
|
||||
new Class[]{String.class, String.class}, new boolean[]{false, false}));
|
||||
lstInstallers.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
jScrollPane12.setViewportView(lstInstallers);
|
||||
|
||||
btnRefresh.setText(C.i18n("ui.button.refresh")); // NOI18N
|
||||
btnRefresh.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnRefreshActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane12, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(btnRefresh, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnInstall, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane12, javax.swing.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(btnInstall)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnRefresh)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void btnInstallActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInstallActionPerformed
|
||||
downloadSelectedRow();
|
||||
}//GEN-LAST:event_btnInstallActionPerformed
|
||||
|
||||
private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
|
||||
refreshVersions();
|
||||
}//GEN-LAST:event_btnRefreshActionPerformed
|
||||
|
||||
transient List<InstallerVersionList.InstallerVersion> versions;
|
||||
InstallerVersionList list;
|
||||
InstallerType id;
|
||||
|
||||
void refreshVersions() {
|
||||
if (loading)
|
||||
return;
|
||||
Task t = list.refresh(new String[] { gsp.getMinecraftVersionFormatted() });
|
||||
if (t != null) {
|
||||
loading = true;
|
||||
DefaultTableModel model = SwingUtils.clearDefaultTable(lstInstallers);
|
||||
model.addRow(new Object[] { C.i18n("message.loading"), "", "" });
|
||||
t.with(new TaskRunnable(this::loadVersions)).setProgressProviderListener(this).runAsync();
|
||||
}
|
||||
}
|
||||
|
||||
boolean loading = false;
|
||||
|
||||
@Override
|
||||
public void setProgress(Task task, int prog, int max) {
|
||||
DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel();
|
||||
if (model.getRowCount() > 0)
|
||||
model.setValueAt(C.i18n("message.loading") + " " + (prog < 0 ? "???" : Integer.toString(prog * 100 / max) + "%"), 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(Task task, String sta) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressProviderDone(Task task) {
|
||||
loading = false;
|
||||
DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel();
|
||||
if (model.getRowCount() > 0)
|
||||
model.removeRow(0);
|
||||
}
|
||||
|
||||
public synchronized InstallerVersionList.InstallerVersion getVersion(int idx) {
|
||||
return versions.get(idx);
|
||||
}
|
||||
|
||||
synchronized void downloadSelectedRow() {
|
||||
int idx = lstInstallers.getSelectedRow();
|
||||
if (versions == null || idx < 0 || idx >= versions.size()) {
|
||||
MessageBox.show(C.i18n("install.not_refreshed"));
|
||||
return;
|
||||
}
|
||||
TaskWindow.factory()
|
||||
.append(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id))
|
||||
.append(new TaskRunnable(() -> gsp.refreshVersions()))
|
||||
.execute();
|
||||
}
|
||||
|
||||
public void loadVersions() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
synchronized (InstallerPanel.this) {
|
||||
DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel();
|
||||
String mcver = StrUtils.formatVersion(gsp.getMinecraftVersionFormatted());
|
||||
versions = list.getVersions(mcver);
|
||||
SwingUtils.clearDefaultTable(lstInstallers);
|
||||
if (versions != null)
|
||||
for (InstallerVersionList.InstallerVersion v : versions)
|
||||
if (v != null)
|
||||
model.addRow(new Object[] { v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean refreshed = false;
|
||||
|
||||
@Override
|
||||
public void onSelect(TopTabPage page) {
|
||||
super.onSelect(page);
|
||||
if (!refreshed) {
|
||||
refreshVersions();
|
||||
refreshed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnInstall;
|
||||
private javax.swing.JButton btnRefresh;
|
||||
private javax.swing.JScrollPane jScrollPane12;
|
||||
private javax.swing.JTable lstInstallers;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.AbstractDocument;
|
||||
import javax.swing.text.BoxView;
|
||||
import javax.swing.text.ComponentView;
|
||||
import javax.swing.text.Element;
|
||||
import javax.swing.text.IconView;
|
||||
import javax.swing.text.LabelView;
|
||||
import javax.swing.text.ParagraphView;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyledEditorKit;
|
||||
import javax.swing.text.View;
|
||||
import javax.swing.text.ViewFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class JLineWrapTextPane extends JTextPane {
|
||||
|
||||
// 内部类
|
||||
// 以下内部类全都用于实现自动强制折行
|
||||
|
||||
private class WarpEditorKit extends StyledEditorKit {
|
||||
|
||||
private ViewFactory defaultFactory = new WarpColumnFactory();
|
||||
|
||||
@Override
|
||||
public ViewFactory getViewFactory() {
|
||||
return defaultFactory;
|
||||
}
|
||||
}
|
||||
|
||||
private class WarpColumnFactory implements ViewFactory {
|
||||
|
||||
public View create(Element elem) {
|
||||
String kind = elem.getName();
|
||||
if (kind != null) {
|
||||
if (kind.equals(AbstractDocument.ContentElementName)) {
|
||||
return new WarpLabelView(elem);
|
||||
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
|
||||
return new ParagraphView(elem);
|
||||
} else if (kind.equals(AbstractDocument.SectionElementName)) {
|
||||
return new BoxView(elem, View.Y_AXIS);
|
||||
} else if (kind.equals(StyleConstants.ComponentElementName)) {
|
||||
return new ComponentView(elem);
|
||||
} else if (kind.equals(StyleConstants.IconElementName)) {
|
||||
return new IconView(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// default to text display
|
||||
return new LabelView(elem);
|
||||
}
|
||||
}
|
||||
|
||||
private class WarpLabelView extends LabelView {
|
||||
|
||||
public WarpLabelView(Element elem) {
|
||||
super(elem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMinimumSpan(int axis) {
|
||||
switch (axis) {
|
||||
case View.X_AXIS:
|
||||
return 0;
|
||||
case View.Y_AXIS:
|
||||
return super.getMinimumSpan(axis);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid axis: " + axis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 本类
|
||||
|
||||
// 构造函数
|
||||
public JLineWrapTextPane() {
|
||||
super();
|
||||
this.setEditorKit(new WarpEditorKit());
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,655 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.ui.Theme;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.core.download.DownloadType;
|
||||
import org.jackhuang.hmcl.util.MathUtils;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.lang.SupportedLocales;
|
||||
import org.jackhuang.hmcl.util.ui.JFontComboBox;
|
||||
import org.jackhuang.hmcl.util.ui.JSystemFileChooser;
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LauncherSettingsPanel extends RepaintPage {
|
||||
|
||||
public LauncherSettingsPanel() {
|
||||
setRepainter(this);
|
||||
}
|
||||
|
||||
void initGui() {
|
||||
initComponents();
|
||||
|
||||
animationEnabled = Settings.getInstance().isEnableAnimation();
|
||||
|
||||
DefaultComboBoxModel<String> d = new DefaultComboBoxModel<>();
|
||||
for (DownloadType type : DownloadType.values())
|
||||
d.addElement(type.getName());
|
||||
cboDownloadSource.setModel(d);
|
||||
|
||||
d = new DefaultComboBoxModel<>();
|
||||
int id = 0;
|
||||
for (SupportedLocales type : SupportedLocales.values()) {
|
||||
d.addElement(type.showString());
|
||||
if (type.name().equals(Settings.getInstance().getLocalization()))
|
||||
id = type.ordinal();
|
||||
}
|
||||
cboLang.setModel(d);
|
||||
cboLang.setSelectedIndex(id);
|
||||
|
||||
DefaultComboBoxModel<Theme> g = new DefaultComboBoxModel<>();
|
||||
for (Theme t : Theme.THEMES.values())
|
||||
g.addElement(t);
|
||||
cboTheme.setModel(g);
|
||||
|
||||
txtBackgroundPath.setText(Settings.getInstance().getBgpath());
|
||||
txtCommonPath.setText(Settings.getInstance().getCommonpath());
|
||||
txtProxyHost.setText(Settings.getInstance().getProxyHost());
|
||||
txtProxyPort.setText(Settings.getInstance().getProxyPort());
|
||||
txtProxyUsername.setText(Settings.getInstance().getProxyUserName());
|
||||
txtProxyPassword.setText(Settings.getInstance().getProxyPassword());
|
||||
spinnerFontSize.setValue(Settings.getInstance().getFontSize());
|
||||
cboFontFamily.setSelectedItem(Settings.getInstance().getFontFamily());
|
||||
cboDownloadSource.setSelectedIndex(Settings.getInstance().getDownloadType());
|
||||
cboTheme.setSelectedItem(Settings.getInstance().getTheme());
|
||||
chkEnableShadow.setSelected(Settings.getInstance().isEnableShadow());
|
||||
chkEnableBlur.setSelected(Settings.getInstance().isEnableBlur());
|
||||
chkEnableAnimation.setSelected(Settings.getInstance().isEnableAnimation());
|
||||
chkDecorated.setSelected(Settings.getInstance().isDecorated());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
initGui();
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
lblModpack = new javax.swing.JLabel();
|
||||
lblRestart = new javax.swing.JLabel();
|
||||
tabLauncherSettings = new NewTabPane();
|
||||
pnlGeneral = new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation());
|
||||
lblProxy = new javax.swing.JLabel();
|
||||
lblProxyHost = new javax.swing.JLabel();
|
||||
txtProxyHost = new javax.swing.JTextField();
|
||||
lblProxyPort = new javax.swing.JLabel();
|
||||
txtProxyPort = new javax.swing.JTextField();
|
||||
lblProxyUserName = new javax.swing.JLabel();
|
||||
txtProxyUsername = new javax.swing.JTextField();
|
||||
lblProxyPassword = new javax.swing.JLabel();
|
||||
txtProxyPassword = new javax.swing.JTextField();
|
||||
cboDownloadSource = new javax.swing.JComboBox();
|
||||
lblDownloadSource = new javax.swing.JLabel();
|
||||
lblCommonPath = new javax.swing.JLabel();
|
||||
txtCommonPath = new javax.swing.JTextField();
|
||||
btnSetCommonPath = new javax.swing.JButton();
|
||||
btnCheckUpdate = new javax.swing.JButton();
|
||||
btnMCBBS = new javax.swing.JButton();
|
||||
cboLang = new javax.swing.JComboBox();
|
||||
lblLang = new javax.swing.JLabel();
|
||||
pnlUI = new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation());
|
||||
lblTheme = new javax.swing.JLabel();
|
||||
cboTheme = new javax.swing.JComboBox();
|
||||
lblBackground = new javax.swing.JLabel();
|
||||
txtBackgroundPath = new javax.swing.JTextField();
|
||||
chkEnableShadow = new javax.swing.JCheckBox();
|
||||
chkEnableBlur = new javax.swing.JCheckBox();
|
||||
chkEnableAnimation = new javax.swing.JCheckBox();
|
||||
chkDecorated = new javax.swing.JCheckBox();
|
||||
btnSelBackgroundPath = new javax.swing.JButton();
|
||||
cboFontFamily = new JFontComboBox();
|
||||
lblFont = new javax.swing.JLabel();
|
||||
spinnerFontSize = new javax.swing.JSpinner();
|
||||
lblExample = new javax.swing.JLabel();
|
||||
pnlAbout = new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation());
|
||||
lblAbout = new javax.swing.JLabel();
|
||||
|
||||
lblModpack.setText(C.i18n("launcher.modpack")); // NOI18N
|
||||
lblModpack.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
|
||||
lblModpack.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
lblModpackMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblRestart.setText(C.i18n("launcher.restart")); // NOI18N
|
||||
|
||||
lblProxy.setText(C.i18n("launcher.proxy")); // NOI18N
|
||||
|
||||
lblProxyHost.setText(C.i18n("proxy.host")); // NOI18N
|
||||
|
||||
txtProxyHost.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtProxyHostFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblProxyPort.setText(C.i18n("proxy.port")); // NOI18N
|
||||
|
||||
txtProxyPort.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtProxyPortFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblProxyUserName.setText(C.i18n("proxy.username")); // NOI18N
|
||||
|
||||
txtProxyUsername.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtProxyUsernameFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblProxyPassword.setText(C.i18n("proxy.password")); // NOI18N
|
||||
|
||||
txtProxyPassword.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtProxyPasswordFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cboDownloadSource.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboDownloadSourceItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblDownloadSource.setText(C.i18n("launcher.download_source")); // NOI18N
|
||||
|
||||
lblCommonPath.setText(C.i18n("launcher.common_location")); // NOI18N
|
||||
|
||||
txtCommonPath.setToolTipText(C.i18n("launcher.commpath_tooltip")); // NOI18N
|
||||
txtCommonPath.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtCommonPathFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnSetCommonPath.setText(C.i18n("ui.button.explore")); // NOI18N
|
||||
btnSetCommonPath.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnSetCommonPathActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnCheckUpdate.setText(C.i18n("launcher.update_launcher")); // NOI18N
|
||||
btnCheckUpdate.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCheckUpdateActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnMCBBS.setText("MCBBS");
|
||||
btnMCBBS.setToolTipText("");
|
||||
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnMCBBSActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cboLang.setModel(new DefaultComboBoxModel(new String[]{C.i18n("color.blue"),C.i18n("color.green"),C.i18n("color.purple"),C.i18n("color.dark_blue"),C.i18n("color.orange"),C.i18n("color.red")}));
|
||||
cboLang.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboLangItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblLang.setText(C.i18n("launcher.lang")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout pnlGeneralLayout = new javax.swing.GroupLayout(pnlGeneral);
|
||||
pnlGeneral.setLayout(pnlGeneralLayout);
|
||||
pnlGeneralLayout.setHorizontalGroup(
|
||||
pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addComponent(btnCheckUpdate)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnMCBBS)
|
||||
.addGap(0, 418, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlGeneralLayout.createSequentialGroup()
|
||||
.addComponent(lblProxy)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(lblProxyHost)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtProxyHost, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblProxyPort)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblProxyUserName)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtProxyUsername, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblProxyPassword)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtProxyPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblDownloadSource)
|
||||
.addComponent(lblCommonPath)
|
||||
.addComponent(lblLang))
|
||||
.addGap(28, 28, 28)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboLang, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addComponent(txtCommonPath)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnSetCommonPath))
|
||||
.addComponent(cboDownloadSource, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addContainerGap())
|
||||
);
|
||||
pnlGeneralLayout.setVerticalGroup(
|
||||
pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblCommonPath)
|
||||
.addComponent(txtCommonPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(btnSetCommonPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblDownloadSource)
|
||||
.addComponent(cboDownloadSource, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cboLang, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblLang))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(txtProxyHost, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblProxy)
|
||||
.addComponent(lblProxyHost)
|
||||
.addComponent(txtProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblProxyPort)
|
||||
.addComponent(txtProxyUsername, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblProxyUserName)
|
||||
.addComponent(txtProxyPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblProxyPassword))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 69, Short.MAX_VALUE)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(btnMCBBS, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
tabLauncherSettings.addTab(C.i18n("launcher.tab.general"), pnlGeneral); // NOI18N
|
||||
|
||||
lblTheme.setText(C.i18n("launcher.theme")); // NOI18N
|
||||
|
||||
cboTheme.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboThemeItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblBackground.setText(C.i18n("launcher.background_location")); // NOI18N
|
||||
lblBackground.setToolTipText("");
|
||||
|
||||
txtBackgroundPath.setToolTipText(C.i18n("launcher.background_tooltip")); // NOI18N
|
||||
txtBackgroundPath.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtBackgroundPathFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkEnableShadow.setText(C.i18n("launcher.enable_shadow")); // NOI18N
|
||||
chkEnableShadow.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkEnableShadowItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkEnableBlur.setText(C.i18n("launcher.enable_blur")); // NOI18N
|
||||
chkEnableBlur.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkEnableBlurItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkEnableAnimation.setText(C.i18n("launcher.enable_animation")); // NOI18N
|
||||
chkEnableAnimation.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkEnableAnimationItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkDecorated.setText(C.i18n("launcher.decorated")); // NOI18N
|
||||
chkDecorated.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkDecoratedItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnSelBackgroundPath.setText(C.i18n("ui.button.explore")); // NOI18N
|
||||
btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnSelBackgroundPathActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cboFontFamily.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboFontFamilyItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblFont.setText(C.i18n("launcher.log_font")); // NOI18N
|
||||
|
||||
spinnerFontSize.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerFontSizeStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblExample.setText("19:10:10 [Client Thread/INFO]: Example");
|
||||
|
||||
javax.swing.GroupLayout pnlUILayout = new javax.swing.GroupLayout(pnlUI);
|
||||
pnlUI.setLayout(pnlUILayout);
|
||||
pnlUILayout.setHorizontalGroup(
|
||||
pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(chkDecorated)
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addComponent(chkEnableShadow)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkEnableBlur)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkEnableAnimation)))
|
||||
.addGap(0, 15, Short.MAX_VALUE))
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblBackground)
|
||||
.addComponent(lblFont)
|
||||
.addComponent(lblTheme))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboTheme, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(txtBackgroundPath)
|
||||
.addComponent(cboFontFamily, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(btnSelBackgroundPath, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(spinnerFontSize)))
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addComponent(lblExample)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))))
|
||||
.addContainerGap())
|
||||
);
|
||||
pnlUILayout.setVerticalGroup(
|
||||
pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlUILayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblBackground)
|
||||
.addComponent(txtBackgroundPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(btnSelBackgroundPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cboFontFamily, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblFont)
|
||||
.addComponent(spinnerFontSize, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblExample)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cboTheme, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblTheme))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
|
||||
.addGroup(pnlUILayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkEnableShadow)
|
||||
.addComponent(chkEnableBlur)
|
||||
.addComponent(chkEnableAnimation))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkDecorated)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
tabLauncherSettings.addTab(C.i18n("launcher.tab.ui"), pnlUI); // NOI18N
|
||||
|
||||
lblAbout.setText(C.i18n("launcher.about")); // NOI18N
|
||||
lblAbout.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
|
||||
|
||||
javax.swing.GroupLayout pnlAboutLayout = new javax.swing.GroupLayout(pnlAbout);
|
||||
pnlAbout.setLayout(pnlAboutLayout);
|
||||
pnlAboutLayout.setHorizontalGroup(
|
||||
pnlAboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlAboutLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(104, Short.MAX_VALUE))
|
||||
);
|
||||
pnlAboutLayout.setVerticalGroup(
|
||||
pnlAboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlAboutLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
tabLauncherSettings.addTab(C.i18n("launcher.tab.about"), pnlAbout); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblRestart))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(tabLauncherSettings)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(tabLauncherSettings)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblRestart)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
tabLauncherSettings.getAccessibleContext().setAccessibleName("");
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void cboDownloadSourceItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboDownloadSourceItemStateChanged
|
||||
Settings.getInstance().setDownloadType(cboDownloadSource.getSelectedIndex());
|
||||
}//GEN-LAST:event_cboDownloadSourceItemStateChanged
|
||||
|
||||
private void btnSelBackgroundPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelBackgroundPathActionPerformed
|
||||
JSystemFileChooser fc = new JSystemFileChooser();
|
||||
fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY);
|
||||
fc.setDialogTitle(C.i18n("launcher.choose_bgpath"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.setFileFilter(new FileNameExtensionFilter("*.png", "png"));
|
||||
fc.addChoosableFileFilter(new FileNameExtensionFilter("*.jpg", "jpg"));
|
||||
if (fc.showOpenDialog(this) != JSystemFileChooser.APPROVE_OPTION || fc.getSelectedFile() == null)
|
||||
return;
|
||||
try {
|
||||
String path = fc.getSelectedFile().getCanonicalPath();
|
||||
path = IOUtils.removeLastSeparator(path);
|
||||
txtBackgroundPath.setText(path);
|
||||
Settings.getInstance().setBgpath(path);
|
||||
MainFrame.INSTANCE.loadBackground();
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to set background path.", e);
|
||||
MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage());
|
||||
}
|
||||
}//GEN-LAST:event_btnSelBackgroundPathActionPerformed
|
||||
|
||||
private void txtBackgroundPathFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtBackgroundPathFocusLost
|
||||
Settings.getInstance().setBgpath(txtBackgroundPath.getText());
|
||||
MainFrame.INSTANCE.loadBackground();
|
||||
}//GEN-LAST:event_txtBackgroundPathFocusLost
|
||||
|
||||
private void btnCheckUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckUpdateActionPerformed
|
||||
Settings.UPDATE_CHECKER.process(true);
|
||||
Settings.UPDATE_CHECKER.checkOutdate();
|
||||
}//GEN-LAST:event_btnCheckUpdateActionPerformed
|
||||
|
||||
private void cboThemeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboThemeItemStateChanged
|
||||
Settings.getInstance().setTheme(((Theme) cboTheme.getSelectedItem()).id);
|
||||
}//GEN-LAST:event_cboThemeItemStateChanged
|
||||
|
||||
private void lblModpackMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModpackMouseClicked
|
||||
SwingUtils.openLink("http://huangyuhui.duapp.com/link.php?type=modpack");
|
||||
}//GEN-LAST:event_lblModpackMouseClicked
|
||||
|
||||
private void cboLangItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLangItemStateChanged
|
||||
Settings.getInstance().setLocalization(SupportedLocales.values()[cboLang.getSelectedIndex()].name());
|
||||
}//GEN-LAST:event_cboLangItemStateChanged
|
||||
|
||||
private void chkEnableShadowItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkEnableShadowItemStateChanged
|
||||
Settings.getInstance().setEnableShadow(chkEnableShadow.isSelected());
|
||||
}//GEN-LAST:event_chkEnableShadowItemStateChanged
|
||||
|
||||
private void chkDecoratedItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkDecoratedItemStateChanged
|
||||
Settings.getInstance().setDecorated(chkDecorated.isSelected());
|
||||
}//GEN-LAST:event_chkDecoratedItemStateChanged
|
||||
|
||||
private void txtProxyHostFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProxyHostFocusLost
|
||||
Settings.getInstance().setProxyHost(txtProxyHost.getText());
|
||||
}//GEN-LAST:event_txtProxyHostFocusLost
|
||||
|
||||
private void txtProxyPortFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProxyPortFocusLost
|
||||
Settings.getInstance().setProxyPort(txtProxyPort.getText());
|
||||
}//GEN-LAST:event_txtProxyPortFocusLost
|
||||
|
||||
private void txtProxyUsernameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProxyUsernameFocusLost
|
||||
Settings.getInstance().setProxyUserName(txtProxyUsername.getText());
|
||||
}//GEN-LAST:event_txtProxyUsernameFocusLost
|
||||
|
||||
private void txtProxyPasswordFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProxyPasswordFocusLost
|
||||
Settings.getInstance().setProxyPassword(txtProxyPassword.getText());
|
||||
}//GEN-LAST:event_txtProxyPasswordFocusLost
|
||||
|
||||
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
|
||||
SwingUtils.openLink(C.URL_PUBLISH);
|
||||
}//GEN-LAST:event_btnMCBBSActionPerformed
|
||||
|
||||
private void chkEnableBlurItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkEnableBlurItemStateChanged
|
||||
Settings.getInstance().setEnableBlur(chkEnableBlur.isSelected());
|
||||
}//GEN-LAST:event_chkEnableBlurItemStateChanged
|
||||
|
||||
private void chkEnableAnimationItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkEnableAnimationItemStateChanged
|
||||
Settings.getInstance().setEnableAnimation(chkEnableAnimation.isSelected());
|
||||
}//GEN-LAST:event_chkEnableAnimationItemStateChanged
|
||||
|
||||
private void btnSetCommonPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSetCommonPathActionPerformed
|
||||
JSystemFileChooser fc = new JSystemFileChooser();
|
||||
fc.setFileSelectionMode(JSystemFileChooser.DIRECTORIES_ONLY);
|
||||
fc.setDialogTitle(C.i18n("launcher.choose_commonpath"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
if (fc.showOpenDialog(this) != JSystemFileChooser.APPROVE_OPTION || fc.getSelectedFile() == null)
|
||||
return;
|
||||
try {
|
||||
String path = fc.getSelectedFile().getCanonicalPath();
|
||||
txtCommonPath.setText(path);
|
||||
Settings.getInstance().setCommonpath(path);
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to set common path.", e);
|
||||
MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage());
|
||||
}
|
||||
}//GEN-LAST:event_btnSetCommonPathActionPerformed
|
||||
|
||||
private void txtCommonPathFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtCommonPathFocusLost
|
||||
Settings.getInstance().setCommonpath(txtCommonPath.getText());
|
||||
}//GEN-LAST:event_txtCommonPathFocusLost
|
||||
|
||||
private void cboFontFamilyItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboFontFamilyItemStateChanged
|
||||
Settings.getInstance().setFontFamily(evt.getItem().toString());
|
||||
lblExample.setFont(Settings.getInstance().getConsoleFont());
|
||||
}//GEN-LAST:event_cboFontFamilyItemStateChanged
|
||||
|
||||
private void spinnerFontSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerFontSizeStateChanged
|
||||
Settings.getInstance().setFontSize(MathUtils.parseInt(spinnerFontSize.getValue().toString(), 12));
|
||||
lblExample.setFont(Settings.getInstance().getConsoleFont());
|
||||
}//GEN-LAST:event_spinnerFontSizeStateChanged
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCheckUpdate;
|
||||
private javax.swing.JButton btnMCBBS;
|
||||
private javax.swing.JButton btnSelBackgroundPath;
|
||||
private javax.swing.JButton btnSetCommonPath;
|
||||
private javax.swing.JComboBox cboDownloadSource;
|
||||
private javax.swing.JComboBox cboFontFamily;
|
||||
private javax.swing.JComboBox cboLang;
|
||||
private javax.swing.JComboBox cboTheme;
|
||||
private javax.swing.JCheckBox chkDecorated;
|
||||
private javax.swing.JCheckBox chkEnableAnimation;
|
||||
private javax.swing.JCheckBox chkEnableBlur;
|
||||
private javax.swing.JCheckBox chkEnableShadow;
|
||||
private javax.swing.JLabel lblAbout;
|
||||
private javax.swing.JLabel lblBackground;
|
||||
private javax.swing.JLabel lblCommonPath;
|
||||
private javax.swing.JLabel lblDownloadSource;
|
||||
private javax.swing.JLabel lblExample;
|
||||
private javax.swing.JLabel lblFont;
|
||||
private javax.swing.JLabel lblLang;
|
||||
private javax.swing.JLabel lblModpack;
|
||||
private javax.swing.JLabel lblProxy;
|
||||
private javax.swing.JLabel lblProxyHost;
|
||||
private javax.swing.JLabel lblProxyPassword;
|
||||
private javax.swing.JLabel lblProxyPort;
|
||||
private javax.swing.JLabel lblProxyUserName;
|
||||
private javax.swing.JLabel lblRestart;
|
||||
private javax.swing.JLabel lblTheme;
|
||||
private javax.swing.JPanel pnlAbout;
|
||||
private javax.swing.JPanel pnlGeneral;
|
||||
private javax.swing.JPanel pnlUI;
|
||||
private javax.swing.JSpinner spinnerFontSize;
|
||||
private javax.swing.JTabbedPane tabLauncherSettings;
|
||||
private javax.swing.JTextField txtBackgroundPath;
|
||||
private javax.swing.JTextField txtCommonPath;
|
||||
private javax.swing.JTextField txtProxyHost;
|
||||
private javax.swing.JTextField txtProxyPassword;
|
||||
private javax.swing.JTextField txtProxyPort;
|
||||
private javax.swing.JTextField txtProxyUsername;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedOutputStream;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.process.JVMLaunchFailedEvent;
|
||||
import org.jackhuang.hmcl.api.event.process.JavaProcessExitedAbnormallyEvent;
|
||||
import org.jackhuang.hmcl.api.event.process.JavaProcessStoppedEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchSucceededEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingStateChangedEvent;
|
||||
import org.jackhuang.hmcl.util.LauncherVisibility;
|
||||
import org.jackhuang.hmcl.core.launch.GameLauncher;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.HMCLGameLauncher;
|
||||
import org.jackhuang.hmcl.util.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingState;
|
||||
import org.jackhuang.hmcl.util.DefaultPlugin;
|
||||
import org.jackhuang.hmcl.util.Log4jHandler;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.sys.PrintlnEvent;
|
||||
import org.jackhuang.hmcl.util.sys.ProcessMonitor;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchingUIDaemon {
|
||||
|
||||
XMLReader reader;
|
||||
|
||||
public LaunchingUIDaemon() {
|
||||
HMCLApi.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(LAUNCHING_STATE_CHANGED);
|
||||
HMCLApi.EVENT_BUS.channel(LaunchEvent.class).register(p -> {
|
||||
GameLauncher obj = (GameLauncher) p.getSource();
|
||||
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) obj.getTag();
|
||||
if (tag.launcherVisibility == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
|
||||
HMCLog.log("Without the option of keeping the launcher visible, this application will exit and will NOT catch game logs, but you can turn on \"Debug Mode\".");
|
||||
System.exit(0);
|
||||
} else if (tag.launcherVisibility == LauncherVisibility.KEEP)
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
else {
|
||||
if (LogWindow.INSTANCE.isVisible())
|
||||
LogWindow.INSTANCE.setExit(() -> true);
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(obj, LaunchingState.WaitingForGameLaunching));
|
||||
}
|
||||
// We promise that JavaProcessMonitor.tag is LauncherVisibility
|
||||
// See events below.
|
||||
ProcessMonitor monitor = new ProcessMonitor(p.getValue());
|
||||
PipedOutputStream os = new PipedOutputStream();
|
||||
monitor.setTag(obj);
|
||||
try {
|
||||
Log4jHandler handler = new Log4jHandler(monitor, os);
|
||||
handler.addForbiddenToken(obj.getLoginResult().getAccessToken(), "<access token>");
|
||||
handler.addForbiddenToken(obj.getLoginResult().getSession(), "<session>");
|
||||
handler.addForbiddenToken(obj.getLoginResult().getUserId(), "<uuid>");
|
||||
handler.addForbiddenToken("Setting user: " + obj.getLoginResult().getUserName(), "<player>");
|
||||
handler.start();
|
||||
} catch(Exception e) {
|
||||
HMCLog.err("", e);
|
||||
}
|
||||
monitor.registerPrintlnEvent(new PrintlnProcessor(obj, os));
|
||||
monitor.start();
|
||||
});
|
||||
HMCLApi.EVENT_BUS.channel(LaunchSucceededEvent.class).register(p -> {
|
||||
int state = ((HMCLGameLauncher.GameLauncherTag) ((GameLauncher) p.getSource()).getTag()).state;
|
||||
if (state == 1)
|
||||
LAUNCH_FINISHER.accept(p);
|
||||
else if (state == 2)
|
||||
LAUNCH_SCRIPT_FINISHER.accept(p);
|
||||
});
|
||||
HMCLApi.EVENT_BUS.channel(JavaProcessStoppedEvent.class).register(event -> {
|
||||
GameLauncher launcher = ((GameLauncher) ((ProcessMonitor) event.getSource()).getTag());
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(launcher, LaunchingState.Done));
|
||||
checkExit(unpackProcessMonitor(event.getSource()));
|
||||
});
|
||||
HMCLApi.EVENT_BUS.channel(JavaProcessExitedAbnormallyEvent.class).register(event -> {
|
||||
ProcessMonitor monitor = (ProcessMonitor) event.getSource();
|
||||
int exitCode = event.getValue().getExitCode();
|
||||
HMCLog.err("The game exited abnormally, exit code: " + exitCode);
|
||||
monitor.waitForCommandLineCompletion();
|
||||
String[] logs = event.getValue().getStdOutLines().toArray(new String[0]);
|
||||
String errorText = null;
|
||||
for (String s : logs) {
|
||||
int pos = s.lastIndexOf("#@!@#");
|
||||
if (pos >= 0 && pos < s.length() - "#@!@#".length() - 1) {
|
||||
errorText = s.substring(pos + "#@!@#".length()).trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
String msg = C.i18n("launch.exited_abnormally") + " exit code: " + exitCode;
|
||||
if (errorText != null)
|
||||
msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readQuietly(new File(errorText)));
|
||||
HMCLog.err(msg);
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
|
||||
noExitThisTime = true;
|
||||
});
|
||||
HMCLApi.EVENT_BUS.channel(JVMLaunchFailedEvent.class).register(event -> {
|
||||
int exitCode = event.getValue().getExitCode();
|
||||
HMCLog.err("Cannot create jvm, exit code: " + exitCode);
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
|
||||
noExitThisTime = true;
|
||||
});
|
||||
}
|
||||
|
||||
static LauncherVisibility unpackProcessMonitor(Object obj) {
|
||||
GameLauncher launcher = ((GameLauncher) ((ProcessMonitor) obj).getTag());
|
||||
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) launcher.getTag();
|
||||
return tag.launcherVisibility;
|
||||
}
|
||||
|
||||
boolean noExitThisTime = false;
|
||||
|
||||
void runGame(Profile profile) {
|
||||
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
|
||||
profile.launcher().genLaunchCode(value -> {
|
||||
DefaultPlugin.INSTANCE.saveAuthenticatorConfig();
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 1;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
|
||||
void testGame(Profile profile) {
|
||||
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
|
||||
profile.launcher().genLaunchCode(value -> {
|
||||
DefaultPlugin.INSTANCE.saveAuthenticatorConfig();
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 1;
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).launcherVisibility = LauncherVisibility.KEEP;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
|
||||
void makeLaunchScript(Profile profile) {
|
||||
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
|
||||
profile.launcher().genLaunchCode(value -> {
|
||||
DefaultPlugin.INSTANCE.saveAuthenticatorConfig();
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 2;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
|
||||
class PrintlnProcessor implements Consumer<PrintlnEvent> {
|
||||
|
||||
GameLauncher launcher;
|
||||
PipedOutputStream os;
|
||||
|
||||
public PrintlnProcessor(GameLauncher launcher, PipedOutputStream os) {
|
||||
this.launcher = launcher;
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(PrintlnEvent t) {
|
||||
if (!t.isError())
|
||||
try {
|
||||
os.write((t.getLine() + C.LINE_SEPARATOR).replace("log4j:Event", "log4j_Event").replace("log4j:Message", "log4j_Message").getBytes());
|
||||
os.flush();
|
||||
} catch(IOException e) {
|
||||
HMCLog.err("", e);
|
||||
}
|
||||
else System.err.println(t.getLine());
|
||||
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) launcher.getTag();
|
||||
LauncherVisibility l = tag.launcherVisibility;
|
||||
if (t.getLine().contains("LWJGL Version: ") && l != LauncherVisibility.KEEP)
|
||||
if (l != LauncherVisibility.HIDE_AND_REOPEN)
|
||||
MainFrame.INSTANCE.dispose();
|
||||
else { // If current state is 'hide and reopen', closes the main window and reset the state to normal.
|
||||
MainFrame.INSTANCE.setVisible(false);
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(launcher, LaunchingState.Done));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Consumer<LaunchingStateChangedEvent> LAUNCHING_STATE_CHANGED = t -> {
|
||||
String message = null;
|
||||
switch (t.getValue()) {
|
||||
case LoggingIn:
|
||||
message = "launch.state.logging_in";
|
||||
break;
|
||||
case GeneratingLaunchingCodes:
|
||||
message = "launch.state.generating_launching_codes";
|
||||
break;
|
||||
case DownloadingLibraries:
|
||||
message = "launch.state.downloading_libraries";
|
||||
break;
|
||||
case DecompressingNatives:
|
||||
message = "launch.state.decompressing_natives";
|
||||
break;
|
||||
case WaitingForGameLaunching:
|
||||
message = "launch.state.waiting_launching";
|
||||
break;
|
||||
case Done:
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
return;
|
||||
}
|
||||
MainFrame.INSTANCE.showMessage(C.i18n(message));
|
||||
};
|
||||
|
||||
private static final Consumer<LaunchSucceededEvent> LAUNCH_FINISHER = event -> {
|
||||
try {
|
||||
((GameLauncher) event.getSource()).launch(event.getValue());
|
||||
} catch (IOException e) {
|
||||
MainFrame.INSTANCE.failed(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage());
|
||||
HMCLog.err("Failed to launch when creating a new process.", e);
|
||||
}
|
||||
};
|
||||
|
||||
private void checkExit(LauncherVisibility v) {
|
||||
if (v == LauncherVisibility.HIDE_AND_REOPEN) {
|
||||
HMCLog.log("Launcher will not exit now.");
|
||||
MainFrame.INSTANCE.setVisible(true);
|
||||
} else if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible() && !noExitThisTime) {
|
||||
HMCLog.log("Launcher will exit now.");
|
||||
System.exit(0);
|
||||
} else {
|
||||
HMCLog.log("Launcher will not exit now.");
|
||||
noExitThisTime = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Consumer<LaunchSucceededEvent> LAUNCH_SCRIPT_FINISHER = event -> {
|
||||
try {
|
||||
String s = MessageBox.showInputDialog(C.i18n("mainwindow.enter_script_name"));
|
||||
if (StrUtils.isNotBlank(s))
|
||||
MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) event.getSource()).makeLauncher(s, event.getValue()).getAbsolutePath());
|
||||
} catch (IOException ex) {
|
||||
MessageBox.show(C.i18n("mainwindow.make_launch_script_failed"));
|
||||
HMCLog.err("Failed to create script file.", ex);
|
||||
}
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="logwindow.title" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="btnContact" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="144" max="32767" attributes="0"/>
|
||||
<Component id="btnTerminateGame" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnCopy" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnClear" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnClose" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="lblCrash" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblShowLines" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cboShowLines" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblSearch" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtSearch" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnFatal" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnError" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnWarn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnInfo" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnDebug" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="pnlLog" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblShowLines" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboShowLines" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnDebug" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnInfo" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnWarn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnError" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnFatal" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtSearch" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblSearch" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblCrash" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pnlLog" pref="281" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnClear" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnClose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnContact" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btnClear">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="ui.button.clear" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnClearActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnClose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="ui.button.close" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCloseActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnCopy">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="ui.button.copy" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCopyActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblCrash">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="ui.label.crashing" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnContact">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="logwindow.contact" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnContactActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnTerminateGame">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="logwindow.terminate_game" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTerminateGameActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="pnlLog">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextPane" name="txtLog">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JLineWrapTextPane()"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="lblShowLines">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="logwindow.show_lines" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboShowLines">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="3">
|
||||
<StringItem index="0" value="100"/>
|
||||
<StringItem index="1" value="1000"/>
|
||||
<StringItem index="2" value="5000"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboShowLinesItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="btnDebug">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="0 debug"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="btnInfo">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="0 info"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="btnWarn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="0 warn"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnError">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="0 error"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnFatal">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="0 fatal"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtSearch">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtSearchActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblSearch">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="logwindow.search" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,425 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyledDocument;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.log.Level;
|
||||
import org.jackhuang.hmcl.api.func.NonFunction;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.DoubleOutputStream;
|
||||
import org.jackhuang.hmcl.util.Utils;
|
||||
import org.jackhuang.hmcl.util.sys.ProcessMonitor;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LogWindow extends javax.swing.JFrame {
|
||||
|
||||
public static LogWindowOutputStream outputStream;
|
||||
|
||||
NonFunction<Boolean> listener;
|
||||
|
||||
/**
|
||||
* Creates new form LogWindow
|
||||
*/
|
||||
public LogWindow() {
|
||||
initComponents();
|
||||
|
||||
DoubleOutputStream out = new DoubleOutputStream(outputStream = new LogWindowOutputStream(this, Level.INFO), System.out);
|
||||
System.setOut(new PrintStream(out));
|
||||
DoubleOutputStream err = new DoubleOutputStream(new LogWindowOutputStream(this, Level.ERROR), System.err);
|
||||
System.setErr(new PrintStream(err));
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setLocationRelativeTo(null);
|
||||
//txtLog.setEditable(false);
|
||||
txtLog.setFont(Settings.getInstance().getConsoleFont());
|
||||
cboShowLines.setSelectedItem(String.valueOf(Settings.getInstance().getLogLines()));
|
||||
});
|
||||
}
|
||||
|
||||
public static final LogWindow INSTANCE = new LogWindow();
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
btnClear = new javax.swing.JButton();
|
||||
btnClose = new javax.swing.JButton();
|
||||
btnCopy = new javax.swing.JButton();
|
||||
lblCrash = new javax.swing.JLabel();
|
||||
btnContact = new javax.swing.JButton();
|
||||
btnTerminateGame = new javax.swing.JButton();
|
||||
pnlLog = new javax.swing.JScrollPane();
|
||||
txtLog = new JLineWrapTextPane();
|
||||
lblShowLines = new javax.swing.JLabel();
|
||||
cboShowLines = new javax.swing.JComboBox<>();
|
||||
btnDebug = new javax.swing.JToggleButton();
|
||||
btnInfo = new javax.swing.JToggleButton();
|
||||
btnWarn = new javax.swing.JToggleButton();
|
||||
btnError = new javax.swing.JButton();
|
||||
btnFatal = new javax.swing.JButton();
|
||||
txtSearch = new javax.swing.JTextField();
|
||||
lblSearch = new javax.swing.JLabel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(C.i18n("logwindow.title")); // NOI18N
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosing(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnClear.setText(C.i18n("ui.button.clear")); // NOI18N
|
||||
btnClear.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnClearActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnClose.setText(C.i18n("ui.button.close")); // NOI18N
|
||||
btnClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnCopy.setText(C.i18n("ui.button.copy")); // NOI18N
|
||||
btnCopy.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCopyActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N
|
||||
|
||||
btnContact.setText(C.i18n("logwindow.contact")); // NOI18N
|
||||
btnContact.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnContactActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnTerminateGame.setText(C.i18n("logwindow.terminate_game")); // NOI18N
|
||||
btnTerminateGame.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnTerminateGameActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
txtLog.setEditable(false);
|
||||
pnlLog.setViewportView(txtLog);
|
||||
|
||||
lblShowLines.setText(C.i18n("logwindow.show_lines")); // NOI18N
|
||||
lblShowLines.setToolTipText("");
|
||||
|
||||
cboShowLines.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "100", "1000", "5000" }));
|
||||
cboShowLines.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboShowLinesItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnDebug.setText("0 debug");
|
||||
|
||||
btnInfo.setText("0 info");
|
||||
|
||||
btnWarn.setText("0 warn");
|
||||
|
||||
btnError.setText("0 error");
|
||||
|
||||
btnFatal.setText("0 fatal");
|
||||
|
||||
txtSearch.setToolTipText("");
|
||||
txtSearch.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtSearchActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblSearch.setText(C.i18n("logwindow.search")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(btnContact)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 144, Short.MAX_VALUE)
|
||||
.addComponent(btnTerminateGame)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnCopy)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnClear)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnClose))
|
||||
.addComponent(lblCrash, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblShowLines)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblSearch)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtSearch)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnFatal)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnError)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnWarn)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnInfo)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnDebug))
|
||||
.addComponent(pnlLog))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblShowLines)
|
||||
.addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(btnDebug)
|
||||
.addComponent(btnInfo)
|
||||
.addComponent(btnWarn)
|
||||
.addComponent(btnError)
|
||||
.addComponent(btnFatal)
|
||||
.addComponent(txtSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblSearch))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblCrash)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnClear)
|
||||
.addComponent(btnClose)
|
||||
.addComponent(btnCopy)
|
||||
.addComponent(btnContact)
|
||||
.addComponent(btnTerminateGame))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCloseActionPerformed
|
||||
if (listener != null && listener.apply())
|
||||
terminateGames();
|
||||
SwingUtils.exitIfNoWindow(this, true);
|
||||
}//GEN-LAST:event_btnCloseActionPerformed
|
||||
|
||||
private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed
|
||||
clean();
|
||||
}//GEN-LAST:event_btnClearActionPerformed
|
||||
|
||||
private void btnCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCopyActionPerformed
|
||||
Utils.setClipborad(this.txtLog.getText());
|
||||
}//GEN-LAST:event_btnCopyActionPerformed
|
||||
|
||||
private void btnContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnContactActionPerformed
|
||||
SwingUtils.openLink(C.URL_CONTACT);
|
||||
}//GEN-LAST:event_btnContactActionPerformed
|
||||
|
||||
private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed
|
||||
terminateGames();
|
||||
}//GEN-LAST:event_btnTerminateGameActionPerformed
|
||||
|
||||
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
|
||||
if (listener != null && listener.apply())
|
||||
terminateGames();
|
||||
SwingUtils.exitIfNoWindow(this);
|
||||
}//GEN-LAST:event_formWindowClosing
|
||||
|
||||
private void cboShowLinesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboShowLinesItemStateChanged
|
||||
Settings.getInstance().setLogLines(Integer.parseInt(cboShowLines.getSelectedItem().toString()));
|
||||
}//GEN-LAST:event_cboShowLinesItemStateChanged
|
||||
|
||||
private void txtSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtSearchActionPerformed
|
||||
if (evt.getSource() != txtSearch || txtSearch.getText().isEmpty())
|
||||
return;
|
||||
try {
|
||||
if (!s.equals(txtSearch.getText()))
|
||||
pos = 0;
|
||||
StyledDocument d = txtLog.getStyledDocument();
|
||||
s = txtSearch.getText();
|
||||
String content = d.getText(0, d.getLength());
|
||||
int x = content.indexOf(s, pos);
|
||||
if (x == -1) {
|
||||
pos = 0;
|
||||
x = content.indexOf(s, pos);
|
||||
}
|
||||
if (x == -1)
|
||||
return;
|
||||
int len = s.length();
|
||||
pos = x + len;
|
||||
SimpleAttributeSet set = new SimpleAttributeSet(d.getLogicalStyle(x).copyAttributes());
|
||||
StyleConstants.setBackground(set, txtLog.getSelectionColor());
|
||||
StyleConstants.setForeground(set, txtLog.getSelectedTextColor());
|
||||
d.setCharacterAttributes(x, len, set, true);
|
||||
set = new SimpleAttributeSet(d.getLogicalStyle(lastX).copyAttributes());
|
||||
StyleConstants.setBackground(set, txtLog.getBackground());
|
||||
StyleConstants.setForeground(set, txtLog.getForeground());
|
||||
d.setCharacterAttributes(lastX, lastLen, set, true);
|
||||
txtLog.select(x, pos);
|
||||
lastX = x;
|
||||
lastLen = len;
|
||||
} catch (BadLocationException e) {
|
||||
}
|
||||
}//GEN-LAST:event_txtSearchActionPerformed
|
||||
|
||||
String s = "";
|
||||
int pos = 0, lastX = 0, lastLen = 0;
|
||||
|
||||
void terminateGames() {
|
||||
ProcessMonitor.stopAll();
|
||||
}
|
||||
|
||||
int removedLength = 0;
|
||||
Deque<Integer> offsets = new LinkedList<>();
|
||||
int fatals = 0, errors = 0, warns = 0, infos = 0, debugs = 0;
|
||||
|
||||
public void log(final String status, final Level c) {
|
||||
if (!isVisible())
|
||||
return;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Document d = txtLog.getStyledDocument();
|
||||
try { // prevent too much memory used.
|
||||
if (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() > 1l * 1024 * 1024 * 256) {
|
||||
d.remove(0, d.getLength());
|
||||
offsets.clear();
|
||||
removedLength = 0;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
HMCLog.err("Failed to clear the text component", ex);
|
||||
}
|
||||
String newStatus = status.replace("\t", " ");
|
||||
SimpleAttributeSet sas = new SimpleAttributeSet();
|
||||
StyleConstants.setForeground(sas, c.COLOR);
|
||||
try {
|
||||
offsets.add(d.getLength() + removedLength);
|
||||
d.insertString(d.getLength(), newStatus, sas);
|
||||
} catch (Exception ex) {
|
||||
HMCLog.err("Failed to insert \"" + newStatus + "\" to " + d.getLength(), ex);
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case FATAL:
|
||||
btnFatal.setText(++fatals + " fatals");
|
||||
break;
|
||||
case ERROR:
|
||||
btnError.setText(++errors + " errors");
|
||||
break;
|
||||
case WARN:
|
||||
btnWarn.setText(++warns + " warns");
|
||||
break;
|
||||
case INFO:
|
||||
btnInfo.setText(++infos + " infos");
|
||||
break;
|
||||
case DEBUG:
|
||||
btnDebug.setText(++debugs + " debugs");
|
||||
break;
|
||||
}
|
||||
|
||||
int maxLines = Integer.parseInt(cboShowLines.getSelectedItem().toString());
|
||||
while (offsets.size() > maxLines) {
|
||||
int start = offsets.pollFirst();
|
||||
int end = offsets.peekFirst();
|
||||
try {
|
||||
d.remove(start - removedLength, end - start); // start - removedLength must become 0
|
||||
removedLength = end;
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setExit(NonFunction<Boolean> exit) {
|
||||
this.listener = exit;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
txtLog.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
txtLog.setFont(Settings.getInstance().getConsoleFont());
|
||||
lblCrash.setVisible(false);
|
||||
btnContact.setVisible(false);
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
public void showAsCrashWindow(boolean out_date) {
|
||||
txtLog.setFont(Settings.getInstance().getConsoleFont());
|
||||
if (out_date) {
|
||||
lblCrash.setVisible(false);
|
||||
btnContact.setVisible(false);
|
||||
lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
|
||||
} else {
|
||||
lblCrash.setVisible(true);
|
||||
btnContact.setVisible(true);
|
||||
lblCrash.setText(C.i18n("ui.label.crashing"));
|
||||
}
|
||||
|
||||
super.setVisible(true);
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnClear;
|
||||
private javax.swing.JButton btnClose;
|
||||
private javax.swing.JButton btnContact;
|
||||
private javax.swing.JButton btnCopy;
|
||||
private javax.swing.JToggleButton btnDebug;
|
||||
private javax.swing.JButton btnError;
|
||||
private javax.swing.JButton btnFatal;
|
||||
private javax.swing.JToggleButton btnInfo;
|
||||
private javax.swing.JButton btnTerminateGame;
|
||||
private javax.swing.JToggleButton btnWarn;
|
||||
private javax.swing.JComboBox<String> cboShowLines;
|
||||
private javax.swing.JLabel lblCrash;
|
||||
private javax.swing.JLabel lblSearch;
|
||||
private javax.swing.JLabel lblShowLines;
|
||||
private javax.swing.JScrollPane pnlLog;
|
||||
private javax.swing.JTextPane txtLog;
|
||||
private javax.swing.JTextField txtSearch;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Objects;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hmcl.util.log.Level;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LogWindowOutputStream extends OutputStream {
|
||||
|
||||
private final LogWindow txt;
|
||||
private final Level sas;
|
||||
|
||||
public LogWindowOutputStream(LogWindow logWindow, Level l) {
|
||||
txt = Objects.requireNonNull(logWindow);
|
||||
sas = Objects.requireNonNull(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void write(byte[] arr) {
|
||||
write(arr, 0, arr.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void write(byte[] arr, int off, int len) {
|
||||
append(new String(arr, off, len));
|
||||
}
|
||||
|
||||
final Object obj = new Object();
|
||||
Level lastLevel = null;
|
||||
|
||||
private void append(final String str) {
|
||||
synchronized(this) {
|
||||
if (manual) return;
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Level level = Level.guessLevel(str);
|
||||
if (level == null) level = lastLevel;
|
||||
else lastLevel = level;
|
||||
txt.log(str, Level.mergeLevel(sas, level));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void write(int i) {
|
||||
append(new String(new byte[] { (byte) i }));
|
||||
}
|
||||
|
||||
boolean manual = false;
|
||||
|
||||
public void log(String s, Level l) {
|
||||
synchronized(this) {
|
||||
manual = true;
|
||||
System.out.print(s);
|
||||
manual = false;
|
||||
}
|
||||
if (l == null) append(s);
|
||||
else
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
txt.log(s, l);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,506 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.GaussionPanel;
|
||||
import org.jackhuang.hmcl.util.ui.IRepaint;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.PluginManager;
|
||||
import org.jackhuang.hmcl.api.event.config.ThemeChangedEvent;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.ui.BasicColors;
|
||||
import org.jackhuang.hmcl.util.ui.DropShadowBorder;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
import org.jackhuang.hmcl.util.ui.TintablePanel;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.api.ui.Theme;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
|
||||
public static final MainFrame INSTANCE = new MainFrame();
|
||||
|
||||
TintablePanel centralPanel;
|
||||
JPanel header, infoSwap, realPanel;
|
||||
CardLayout infoLayout;
|
||||
JLabel windowTitle;
|
||||
GaussionPanel backgroundLabel;
|
||||
DropShadowBorder border;
|
||||
boolean enableShadow;
|
||||
String defaultTitle;
|
||||
|
||||
private int tempW, tempH;
|
||||
|
||||
void setContentSize(int w, int h) {
|
||||
setSize(w, h);
|
||||
tempW = w;
|
||||
tempH = h;
|
||||
}
|
||||
|
||||
MainFrame() {
|
||||
setUndecorated(!Settings.getInstance().isDecorated());
|
||||
defaultTitle = isUndecorated() ? Main.makeTitle() : "";
|
||||
enableShadow = Settings.getInstance().isEnableShadow() && isUndecorated();
|
||||
if (enableShadow)
|
||||
setContentSize(834, 542);
|
||||
else
|
||||
setContentSize(802, 511);
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
setTitle(Main.makeTitle());
|
||||
initComponents();
|
||||
loadBackground();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
if (MainFrame.this.isUndecorated())
|
||||
setResizable(false);
|
||||
|
||||
this.addWindowListener(new WindowListener() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
closing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowIconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(WindowEvent e) {
|
||||
if (!MainFrame.this.isUndecorated()) {
|
||||
int w = tempW + getWidth() - getContentPane().getWidth(), h = tempH + getHeight() - getContentPane().getHeight();
|
||||
setSize(w, h);
|
||||
setResizable(false);
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
if (enableShadow)
|
||||
try {
|
||||
setBackground(new Color(0, 0, 0, 0));
|
||||
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
||||
} catch (Throwable ex) {
|
||||
HMCLog.err("Failed to set window transparent.", ex);
|
||||
Settings.getInstance().setEnableShadow(false);
|
||||
setSize(802, 511);
|
||||
}
|
||||
((JPanel) getContentPane()).setOpaque(true);
|
||||
|
||||
HMCLApi.EVENT_BUS.channel(ThemeChangedEvent.class).register(x -> reloadColor(x.getValue()));
|
||||
|
||||
SwingUtilities.invokeLater(() -> selectTab("main"));
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(null);
|
||||
|
||||
realPanel = new JPanel();
|
||||
realPanel.setLayout(null);
|
||||
|
||||
header = new JPanel();
|
||||
header.setBounds(0, 0, 800, 30);
|
||||
realPanel.add(header);
|
||||
header.setOpaque(true);
|
||||
header.setLayout(new BoxLayout(header, BoxLayout.LINE_AXIS));
|
||||
header.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 5));
|
||||
header.setBackground(borderColor);
|
||||
header.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
|
||||
ImageIcon headerIcon = Main.getIcon("icon.png");
|
||||
this.setIconImage(headerIcon.getImage());
|
||||
headerIcon = SwingUtils.scaleImage(headerIcon, 16, 16);
|
||||
JLabel headerLabel = new JLabel(headerIcon);
|
||||
headerLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
|
||||
header.add(headerLabel);
|
||||
|
||||
header.add(Box.createRigidArea(new Dimension(8, 0)));
|
||||
|
||||
PluginManager.fireAddTab(this, this::initializeTab);
|
||||
|
||||
header.add(Box.createHorizontalGlue());
|
||||
|
||||
JPanel rightHeaderPanel = new JPanel();
|
||||
rightHeaderPanel.setOpaque(false);
|
||||
rightHeaderPanel.setLayout(new BoxLayout(rightHeaderPanel, BoxLayout.PAGE_AXIS));
|
||||
rightHeaderPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
|
||||
|
||||
JPanel windowGadgetPanel = new JPanel();
|
||||
windowGadgetPanel.setOpaque(false);
|
||||
windowGadgetPanel.setLayout(new BoxLayout(windowGadgetPanel, BoxLayout.LINE_AXIS));
|
||||
windowGadgetPanel.setAlignmentX(1.0F);
|
||||
|
||||
if (!Settings.getInstance().isDecorated()) {
|
||||
ImageIcon minimizeIcon = Main.getIcon("minimize.png");
|
||||
JButton minimizeButton = new JButton(minimizeIcon);
|
||||
minimizeButton.setBorder(BorderFactory.createEmptyBorder());
|
||||
minimizeButton.setContentAreaFilled(false);
|
||||
minimizeButton.setCursor(new Cursor(12));
|
||||
minimizeButton.setFocusable(false);
|
||||
minimizeButton.addActionListener((e) -> MainFrame.this.minimizeWindow());
|
||||
windowGadgetPanel.add(minimizeButton);
|
||||
|
||||
ImageIcon closeIcon = Main.getIcon("close.png");
|
||||
JButton closeButton = new JButton(closeIcon);
|
||||
closeButton.setBorder(BorderFactory.createEmptyBorder());
|
||||
closeButton.setContentAreaFilled(false);
|
||||
closeButton.addActionListener((e) -> MainFrame.this.closeWindow());
|
||||
closeButton.setCursor(new Cursor(12));
|
||||
closeButton.setFocusable(false);
|
||||
windowGadgetPanel.add(closeButton);
|
||||
}
|
||||
rightHeaderPanel.add(windowGadgetPanel);
|
||||
|
||||
windowTitle = new JLabel(defaultTitle);
|
||||
windowTitle.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
header.add(windowTitle);
|
||||
header.add(Box.createHorizontalGlue());
|
||||
header.add(rightHeaderPanel);
|
||||
|
||||
this.centralPanel = new TintablePanel();
|
||||
this.centralPanel.setTintColor(BasicColors.COLOR_CENTRAL_BACK);
|
||||
realPanel.add(this.centralPanel);
|
||||
JPanel truePanel = new JPanel();
|
||||
truePanel.setLayout(new BorderLayout());
|
||||
|
||||
this.infoSwap = new JPanel();
|
||||
this.infoLayout = new CardLayout();
|
||||
this.infoSwap.setLayout(infoLayout);
|
||||
this.infoSwap.setOpaque(false);
|
||||
|
||||
tabWrapper = new JPanel[tabHeader.size()];
|
||||
for (int i = 0; i < tabHeader.size(); i++) {
|
||||
tabWrapper[i] = new JPanel();
|
||||
tabWrapper[i].setLayout(new GridLayout());
|
||||
infoSwap.add(tabWrapper[i], tabHeader.get(i).getActionCommand());
|
||||
}
|
||||
|
||||
truePanel.add(this.infoSwap, "Center");
|
||||
centralPanel.setLayout(null);
|
||||
centralPanel.add(truePanel);
|
||||
truePanel.setBounds(0, 0, 800, 480);
|
||||
centralPanel.setBounds(0, 30, 800, 480);
|
||||
|
||||
realPanel.setBounds(1, 0, 800, 511);
|
||||
add(realPanel);
|
||||
|
||||
reloadColor(Settings.getInstance().getTheme());
|
||||
}
|
||||
|
||||
private transient final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand());
|
||||
|
||||
private void initializeTab(TopTabPage inst, String cmd, String title) {
|
||||
HeaderTab tab = new HeaderTab(title);
|
||||
tab.setActionCommand(cmd);
|
||||
tab.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
tab.setBackground(borderColorDarker);
|
||||
tab.setLayout(null);
|
||||
tab.addActionListener(tabListener);
|
||||
header.add(tab);
|
||||
tabHeader.add(tab);
|
||||
tabContent.add(inst);
|
||||
}
|
||||
|
||||
private final List<HeaderTab> tabHeader = new ArrayList<>();
|
||||
private JPanel tabWrapper[];
|
||||
private final List<TopTabPage> tabContent = new ArrayList<>();
|
||||
|
||||
public void selectTab(String tabName) {
|
||||
int chosen = -1;
|
||||
TopTabPage onCreate = null, onSelect = null, lastPage = null;
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (tabName.equalsIgnoreCase(tabHeader.get(i).getActionCommand())) {
|
||||
if (!tabContent.get(i).isCreated()) {
|
||||
onCreate = tabContent.get(i);
|
||||
onCreate.setId(i);
|
||||
tabWrapper[i].add(tabContent.get(i));
|
||||
} else if (tabContent.get(i).isSelected())
|
||||
continue;
|
||||
chosen = i;
|
||||
break;
|
||||
}
|
||||
if (chosen != -1) {
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (i != chosen && tabContent.get(i) != null && tabContent.get(i).isSelected()) {
|
||||
lastPage = tabContent.get(i);
|
||||
lastPage.onLeave();
|
||||
}
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (i == chosen) {
|
||||
for (int j = 0; j < tabHeader.size(); j++)
|
||||
if (j != i)
|
||||
tabHeader.get(j).setIsActive(false);
|
||||
tabHeader.get(i).setIsActive(true);
|
||||
onSelect = tabContent.get(i);
|
||||
}
|
||||
|
||||
this.infoLayout.show(this.infoSwap, tabName);
|
||||
if (onCreate != null)
|
||||
onCreate.onCreate();
|
||||
if (onSelect != null)
|
||||
onSelect.onSelect(lastPage);
|
||||
}
|
||||
}
|
||||
|
||||
protected void closing() {
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (tabContent.get(i) != null && tabContent.get(i).isSelected())
|
||||
tabContent.get(i).onLeave();
|
||||
}
|
||||
|
||||
protected void closeWindow() {
|
||||
closing();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
protected void minimizeWindow() {
|
||||
setState(1);
|
||||
}
|
||||
|
||||
ImageIcon background;
|
||||
|
||||
public void loadBackground() {
|
||||
background = SwingUtils.searchBackgroundImage(Main.getIcon(Settings.getInstance().getTheme().settings.get("Customized.MainFrame.background_image")), Settings.getInstance().getBgpath(), 800, 480);
|
||||
if (background != null) {
|
||||
if (backgroundLabel == null) {
|
||||
backgroundLabel = new GaussionPanel();
|
||||
backgroundLabel.setDrawBackgroundLayer(true);
|
||||
backgroundLabel.addAeroObject(backgroundLabel);
|
||||
backgroundLabel.setBounds(0, 0, 800, 480);
|
||||
centralPanel.add(backgroundLabel, -1);
|
||||
}
|
||||
backgroundLabel.setBackgroundImage(background.getImage());
|
||||
} else
|
||||
HMCLog.warn("No background image here! The background will be empty!");
|
||||
}
|
||||
|
||||
public JPanel getTitleBar() {
|
||||
return header;
|
||||
}
|
||||
|
||||
boolean isShowedMessage = false;
|
||||
|
||||
public void closeMessage() {
|
||||
if (isShowedMessage) {
|
||||
isShowedMessage = false;
|
||||
reloadColor(Settings.getInstance().getTheme());
|
||||
windowTitle.setText(defaultTitle);
|
||||
windowTitle.setForeground(Settings.UPDATE_CHECKER.isOutOfDate() ? Color.red : Color.white);
|
||||
}
|
||||
}
|
||||
|
||||
public void showMessage(String message) {
|
||||
isShowedMessage = true;
|
||||
borderColor = BasicColors.COLOR_RED;
|
||||
borderColorDarker = BasicColors.COLOR_RED_DARKER;
|
||||
header.setBackground(borderColor);
|
||||
for (HeaderTab tab : tabHeader)
|
||||
tab.setBackground(borderColorDarker);
|
||||
if (border != null)
|
||||
border.setColor(borderColor);
|
||||
repaint();
|
||||
windowTitle.setText(message);
|
||||
windowTitle.setForeground(Color.white);
|
||||
}
|
||||
|
||||
public static void showMainFrame() {
|
||||
IAuthenticator l = Settings.getInstance().getAuthenticator();
|
||||
if (StrUtils.isBlank(l.getUserName()))
|
||||
SwingUtilities.invokeLater(() -> MainFrame.INSTANCE.showMessage(C.i18n("ui.message.first_load")));
|
||||
if (l.hasPassword() && !l.isLoggedIn())
|
||||
SwingUtilities.invokeLater(() -> MainFrame.INSTANCE.showMessage(C.i18n("ui.message.enter_password")));
|
||||
INSTANCE.setVisible(true);
|
||||
}
|
||||
|
||||
Color borderColor;
|
||||
Color borderColorDarker;
|
||||
|
||||
private void initBorderColor() {
|
||||
borderColor = UIManager.getColor("Customized.MainFrame.background");
|
||||
borderColorDarker = UIManager.getColor("Customized.MainFrame.selected_background");
|
||||
}
|
||||
|
||||
public void reloadColor(Theme t) {
|
||||
if (isShowedMessage)
|
||||
return;
|
||||
for (Map.Entry<String, String> entry : t.settings.entrySet()) {
|
||||
if (entry.getValue().startsWith("#"))
|
||||
UIManager.put(entry.getKey(), GraphicsUtils.getWebColor(entry.getValue()));
|
||||
}
|
||||
|
||||
initBorderColor();
|
||||
if (border != null)
|
||||
border.setColor(borderColor);
|
||||
header.setBackground(borderColor);
|
||||
for (HeaderTab tab : tabHeader)
|
||||
tab.setBackground(borderColorDarker);
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void paintImpl(Graphics g) {
|
||||
int off = enableShadow ? 16 : 0, yoff = getInsets().top + off, xoff = getInsets().left + off;
|
||||
int width = 800;
|
||||
int height = header.getHeight() + 480 - 1;
|
||||
super.paint(g);
|
||||
g.setColor(borderColor);
|
||||
g.drawLine(xoff, yoff, xoff, height + yoff + 1);
|
||||
g.drawLine(xoff + width + 1, yoff, xoff + width + 1, height + yoff + 1);
|
||||
g.drawLine(xoff, height + yoff + 1, xoff + width + 1, height + yoff + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (!enableShadow)
|
||||
paintImpl(g);
|
||||
else {
|
||||
int off = enableShadow ? 16 : 0;
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
int contentWidth = width - off - off;
|
||||
int contentHeight = height - off - off;
|
||||
BufferedImage contentImage = new BufferedImage(contentWidth,
|
||||
contentHeight, Transparency.OPAQUE);
|
||||
Graphics2D contentG2d = contentImage.createGraphics();
|
||||
contentG2d.translate(-off, -off);
|
||||
paintImpl(g);
|
||||
paintImpl(contentG2d);
|
||||
contentG2d.dispose();
|
||||
g.drawImage(contentImage, off, off, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeUpdate() {
|
||||
defaultTitle = Main.makeTitle() + C.i18n("update.found");
|
||||
windowTitle.addMouseListener(MouseListenerImpl.INSTANCE);
|
||||
if (!isShowedMessage) {
|
||||
windowTitle.setText(defaultTitle);
|
||||
windowTitle.setForeground(Color.red);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getRepaintComponent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getRepaintWindow() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Rectangle> getRepaintRects() {
|
||||
int off = MainFrame.INSTANCE.enableShadow ? 16 : 0, yoff = MainFrame.INSTANCE.getInsets().top + off, xoff = MainFrame.INSTANCE.getInsets().left + off;
|
||||
int width = 800, height = MainFrame.INSTANCE.header.getHeight() + 480 - 1;
|
||||
return Arrays.asList(new Rectangle(xoff, yoff, xoff, height + yoff + 1),
|
||||
new Rectangle(xoff + width + 1, yoff, xoff + width + 1, height + yoff + 1),
|
||||
new Rectangle(xoff, height + yoff + 1, xoff + width + 1, height + yoff + 1));
|
||||
}
|
||||
|
||||
private static class MouseListenerImpl implements MouseListener {
|
||||
|
||||
public static final MouseListenerImpl INSTANCE = new MouseListenerImpl();
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
Settings.UPDATE_CHECKER.checkOutdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void failed(String s) {
|
||||
if (s != null)
|
||||
MessageBox.show(s);
|
||||
closeMessage();
|
||||
}
|
||||
|
||||
transient LaunchingUIDaemon daemon = new LaunchingUIDaemon();
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-32,0,0,3,32"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pnlRoot">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new org.jackhuang.hmcl.launcher.ui.GaussionPanel()"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="0" y="0" width="800" height="480"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pnlMore">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="cc" green="cc" red="cc" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new org.jackhuang.hmcl.launcher.ui.RepaintPage()"/>
|
||||
<AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="MainPagePanel_pnlMore"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="0" y="0" width="190" height="480"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="pnlPassword" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblProfile" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblVersion" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cboProfiles" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cboVersions" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblUserName" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblLogin" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cboLoginMode" max="32767" attributes="0"/>
|
||||
<Component id="txtPlayerName" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="btnExportModpack" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="btnImportModpack" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblProfile" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cboVersions" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblVersion" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblLogin" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboLoginMode" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblUserName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtPlayerName" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pnlPassword" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="254" max="32767" attributes="0"/>
|
||||
<Component id="btnImportModpack" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnExportModpack" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextField" name="txtPlayerName">
|
||||
<Events>
|
||||
<EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPlayerNameFocusGained"/>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPlayerNameFocusLost"/>
|
||||
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtPlayerNameKeyPressed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblLogin">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="login.type" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboLoginMode">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboLoginModeItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblUserName">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="login.username" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblProfile">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.profile" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboProfiles">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboProfilesItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblVersion">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.version" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.version" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboVersions">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboVersionsItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new WideComboBox()"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="pnlPassword">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pnlLogIn">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card2"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblPassword" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtPassword" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblPassword" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
|
||||
<Component id="txtPassword" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblPassword">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.password" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JPasswordField" name="txtPassword">
|
||||
<Events>
|
||||
<EventHandler event="caretUpdate" listener="javax.swing.event.CaretListener" parameters="javax.swing.event.CaretEvent" handler="txtPasswordCaretUpdate"/>
|
||||
<EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPasswordFocusGained"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtPasswordActionPerformed"/>
|
||||
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtPasswordKeyPressed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pnlLogOut">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card3"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="btnLogout" alignment="0" pref="170" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="btnLogout" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btnLogout">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.logout" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnLogoutActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="btnImportModpack">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="modpack.task.install" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnImportModpackActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnExportModpack">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="modpack.task.save" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnExportModpackActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,553 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import org.jackhuang.hmcl.util.ui.WideComboBox;
|
||||
import org.jackhuang.hmcl.util.ui.GaussionPanel;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.config.AuthenticatorChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.config.ProfileChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.config.ProfileLoadingEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchSucceededEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingState;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingStateChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.version.RefreshedVersionsEvent;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.core.auth.AbstractAuthenticator;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.core.mod.ModpackManager;
|
||||
import org.jackhuang.hmcl.ui.modpack.ModpackWizard;
|
||||
import org.jackhuang.hmcl.laf.button.CustomButton;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
import org.jackhuang.hmcl.util.ui.JSystemFileChooser;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.api.WizardDisplayer;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.laf.button.CustomButtonUI;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MainPagePanel extends Page {
|
||||
|
||||
public MainPagePanel() {
|
||||
}
|
||||
|
||||
void initGui() {
|
||||
initComponents();
|
||||
|
||||
animationEnabled = Settings.getInstance().isEnableAnimation();
|
||||
|
||||
pnlButtons = new javax.swing.JPanel();
|
||||
pnlButtons.setLayout(null);
|
||||
|
||||
int w = 150, h = 50;
|
||||
btnRun = new CustomButton();
|
||||
btnRun.setBounds(0, 0, w, h);
|
||||
Font font = btnRun.getFont();
|
||||
Font newFont = new Font(font.getName(), font.getStyle(), 15);
|
||||
pnlButtons.add(btnRun);
|
||||
|
||||
btnRun.setText(C.i18n("ui.button.run"));
|
||||
btnRun.setFont(newFont);
|
||||
btnRun.addActionListener(e -> MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile()));
|
||||
btnRun.setUI(new CustomButtonUI());
|
||||
|
||||
pnlRoot.add(pnlButtons);
|
||||
pnlButtons.setBounds(0, 0, w, h);
|
||||
|
||||
this.setSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
|
||||
this.pnlButtons.setLocation(DEFAULT_WIDTH - pnlButtons.getWidth() - 25, DEFAULT_HEIGHT - pnlButtons.getHeight() - 25);
|
||||
pnlMore.setBounds(0, 0, pnlMore.getWidth(), DEFAULT_HEIGHT);
|
||||
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
|
||||
pnlMore.setOpaque(true);
|
||||
|
||||
if (Settings.getInstance().isEnableBlur())
|
||||
((GaussionPanel) pnlRoot).addAeroObject(pnlMore);
|
||||
((GaussionPanel) pnlRoot).setBackgroundImage(MainFrame.INSTANCE.background.getImage());
|
||||
|
||||
((RepaintPage) pnlMore).setRepainter(pnlRoot);
|
||||
|
||||
HMCLApi.EVENT_BUS.channel(AuthenticatorChangedEvent.class).register(onAuthChanged);
|
||||
HMCLApi.EVENT_BUS.channel(ProfileLoadingEvent.class).register(onLoadingProfiles);
|
||||
HMCLApi.EVENT_BUS.channel(ProfileChangedEvent.class).register(onSelectedProfilesChanged);
|
||||
HMCLApi.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(onRefreshedVersions);
|
||||
HMCLApi.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(launchingStateChanged);
|
||||
HMCLApi.EVENT_BUS.channel(LaunchSucceededEvent.class).register(this::prepareAuths);
|
||||
|
||||
prepareAuths();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
pnlRoot = new GaussionPanel();
|
||||
pnlMore = new org.jackhuang.hmcl.ui.RepaintPage();
|
||||
txtPlayerName = new javax.swing.JTextField();
|
||||
lblLogin = new javax.swing.JLabel();
|
||||
cboLoginMode = new javax.swing.JComboBox();
|
||||
lblUserName = new javax.swing.JLabel();
|
||||
lblProfile = new javax.swing.JLabel();
|
||||
cboProfiles = new javax.swing.JComboBox();
|
||||
lblVersion = new javax.swing.JLabel();
|
||||
cboVersions = new WideComboBox();
|
||||
pnlPassword = new javax.swing.JPanel();
|
||||
pnlLogIn = new javax.swing.JPanel();
|
||||
lblPassword = new javax.swing.JLabel();
|
||||
txtPassword = new javax.swing.JPasswordField();
|
||||
pnlLogOut = new javax.swing.JPanel();
|
||||
btnLogout = new javax.swing.JButton();
|
||||
btnImportModpack = new javax.swing.JButton();
|
||||
btnExportModpack = new javax.swing.JButton();
|
||||
|
||||
setLayout(null);
|
||||
|
||||
pnlRoot.setLayout(null);
|
||||
|
||||
pnlMore.setBackground(new java.awt.Color(204, 204, 204));
|
||||
pnlMore.setOpaque(false);
|
||||
|
||||
txtPlayerName.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusGained(java.awt.event.FocusEvent evt) {
|
||||
txtPlayerNameFocusGained(evt);
|
||||
}
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtPlayerNameFocusLost(evt);
|
||||
}
|
||||
});
|
||||
txtPlayerName.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyPressed(java.awt.event.KeyEvent evt) {
|
||||
txtPlayerNameKeyPressed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblLogin.setText(C.i18n("login.type")); // NOI18N
|
||||
|
||||
cboLoginMode.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboLoginModeItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblUserName.setText(C.i18n("login.username")); // NOI18N
|
||||
|
||||
lblProfile.setText(C.i18n("ui.label.profile")); // NOI18N
|
||||
|
||||
cboProfiles.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboProfilesItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblVersion.setText(C.i18n("ui.label.version")); // NOI18N
|
||||
lblVersion.setToolTipText(C.i18n("ui.label.version")); // NOI18N
|
||||
|
||||
cboVersions.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboVersionsItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pnlPassword.setLayout(new java.awt.CardLayout());
|
||||
|
||||
lblPassword.setText(C.i18n("ui.label.password")); // NOI18N
|
||||
|
||||
txtPassword.addCaretListener(new javax.swing.event.CaretListener() {
|
||||
public void caretUpdate(javax.swing.event.CaretEvent evt) {
|
||||
txtPasswordCaretUpdate(evt);
|
||||
}
|
||||
});
|
||||
txtPassword.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusGained(java.awt.event.FocusEvent evt) {
|
||||
txtPasswordFocusGained(evt);
|
||||
}
|
||||
});
|
||||
txtPassword.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtPasswordActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
txtPassword.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyPressed(java.awt.event.KeyEvent evt) {
|
||||
txtPasswordKeyPressed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout pnlLogInLayout = new javax.swing.GroupLayout(pnlLogIn);
|
||||
pnlLogIn.setLayout(pnlLogInLayout);
|
||||
pnlLogInLayout.setHorizontalGroup(
|
||||
pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlLogInLayout.createSequentialGroup()
|
||||
.addComponent(lblPassword)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtPassword))
|
||||
);
|
||||
pnlLogInLayout.setVerticalGroup(
|
||||
pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlLogInLayout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addGroup(pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
);
|
||||
|
||||
pnlPassword.add(pnlLogIn, "card2");
|
||||
|
||||
btnLogout.setText(C.i18n("ui.button.logout")); // NOI18N
|
||||
btnLogout.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnLogoutActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout pnlLogOutLayout = new javax.swing.GroupLayout(pnlLogOut);
|
||||
pnlLogOut.setLayout(pnlLogOutLayout);
|
||||
pnlLogOutLayout.setHorizontalGroup(
|
||||
pnlLogOutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
|
||||
);
|
||||
pnlLogOutLayout.setVerticalGroup(
|
||||
pnlLogOutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
pnlPassword.add(pnlLogOut, "card3");
|
||||
|
||||
btnImportModpack.setText(C.i18n("modpack.task.install")); // NOI18N
|
||||
btnImportModpack.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnImportModpackActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnExportModpack.setText(C.i18n("modpack.task.save")); // NOI18N
|
||||
btnExportModpack.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnExportModpackActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout pnlMoreLayout = new javax.swing.GroupLayout(pnlMore);
|
||||
pnlMore.setLayout(pnlMoreLayout);
|
||||
pnlMoreLayout.setHorizontalGroup(
|
||||
pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pnlPassword, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblProfile, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(lblVersion, javax.swing.GroupLayout.Alignment.TRAILING))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(cboVersions, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblUserName)
|
||||
.addComponent(lblLogin))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboLoginMode, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(txtPlayerName)))
|
||||
.addComponent(btnExportModpack, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnImportModpack, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
pnlMoreLayout.setVerticalGroup(
|
||||
pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlMoreLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblProfile)
|
||||
.addComponent(cboProfiles, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cboVersions, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblVersion))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblLogin)
|
||||
.addComponent(cboLoginMode, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblUserName)
|
||||
.addComponent(txtPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 254, Short.MAX_VALUE)
|
||||
.addComponent(btnImportModpack)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnExportModpack)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pnlRoot.add(pnlMore);
|
||||
pnlMore.setBounds(0, 0, 190, 480);
|
||||
|
||||
add(pnlRoot);
|
||||
pnlRoot.setBounds(0, 0, 800, 480);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void txtPlayerNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusGained
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
}//GEN-LAST:event_txtPlayerNameFocusGained
|
||||
|
||||
private void txtPlayerNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusLost
|
||||
IAuthenticator l = Settings.getInstance().getAuthenticator();
|
||||
l.setUserName(txtPlayerName.getText());
|
||||
}//GEN-LAST:event_txtPlayerNameFocusLost
|
||||
|
||||
private void cboLoginModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLoginModeItemStateChanged
|
||||
if (evt.getStateChange() != ItemEvent.SELECTED)
|
||||
return;
|
||||
if (preparingAuth)
|
||||
return;
|
||||
Settings.getInstance().setLoginType(cboLoginMode.getSelectedIndex());
|
||||
}//GEN-LAST:event_cboLoginModeItemStateChanged
|
||||
|
||||
private void cboProfilesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProfilesItemStateChanged
|
||||
if (!isLoading && cboProfiles.getSelectedIndex() != -1 && !StrUtils.isBlank((String) cboProfiles.getSelectedItem()))
|
||||
Settings.getInstance().setLast((String) cboProfiles.getSelectedItem());
|
||||
}//GEN-LAST:event_cboProfilesItemStateChanged
|
||||
|
||||
private void cboVersionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboVersionsItemStateChanged
|
||||
if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem()))
|
||||
return;
|
||||
String mcv = (String) cboVersions.getSelectedItem();
|
||||
Settings.getLastProfile().setSelectedVersion(mcv);
|
||||
}//GEN-LAST:event_cboVersionsItemStateChanged
|
||||
|
||||
private void txtPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPasswordFocusGained
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
}//GEN-LAST:event_txtPasswordFocusGained
|
||||
|
||||
private void txtPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtPasswordActionPerformed
|
||||
MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile());
|
||||
}//GEN-LAST:event_txtPasswordActionPerformed
|
||||
|
||||
private void btnLogoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLogoutActionPerformed
|
||||
if (preparingAuth)
|
||||
return;
|
||||
|
||||
IAuthenticator l = Settings.getInstance().getAuthenticator();
|
||||
CardLayout cl = (CardLayout) pnlPassword.getLayout();
|
||||
if (l.isLoggedIn())
|
||||
l.logOut();
|
||||
cl.first(pnlPassword);
|
||||
SwingUtilities.invokeLater(this::repaint);
|
||||
}//GEN-LAST:event_btnLogoutActionPerformed
|
||||
|
||||
private void txtPlayerNameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtPlayerNameKeyPressed
|
||||
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
IAuthenticator l = Settings.getInstance().getAuthenticator();
|
||||
l.setUserName(txtPlayerName.getText());
|
||||
if (!l.hasPassword())
|
||||
MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile());
|
||||
else if (!l.isLoggedIn())
|
||||
txtPassword.requestFocus();
|
||||
}
|
||||
}//GEN-LAST:event_txtPlayerNameKeyPressed
|
||||
|
||||
private void txtPasswordKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtPasswordKeyPressed
|
||||
if (evt.getKeyCode() == KeyEvent.VK_ENTER)
|
||||
MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile());
|
||||
}//GEN-LAST:event_txtPasswordKeyPressed
|
||||
|
||||
private void btnImportModpackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnImportModpackActionPerformed
|
||||
JSystemFileChooser fc = new JSystemFileChooser();
|
||||
fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY);
|
||||
fc.setDialogTitle(C.i18n("modpack.choose"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.setFileFilter(new FileNameExtensionFilter(C.i18n("modpack"), "zip"));
|
||||
fc.showOpenDialog(this);
|
||||
if (fc.getSelectedFile() == null)
|
||||
return;
|
||||
String suggestedModpackId = MessageBox.showInputDialog(C.i18n("modpack.enter_name"), FileUtils.getBaseName(fc.getSelectedFile().getName()));
|
||||
if (StrUtils.isBlank(suggestedModpackId))
|
||||
return;
|
||||
TaskWindow.factory().append(ModpackManager.install(MainFrame.INSTANCE, fc.getSelectedFile(), Settings.getLastProfile().service(), suggestedModpackId)).execute();
|
||||
Settings.getLastProfile().service().version().refreshVersions();
|
||||
}//GEN-LAST:event_btnImportModpackActionPerformed
|
||||
|
||||
private void btnExportModpackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExportModpackActionPerformed
|
||||
if (Settings.getLastProfile().service().version().getVersionCount() <= 0)
|
||||
return;
|
||||
WizardDisplayer.showWizard(new ModpackWizard(Settings.getLastProfile()).createWizard());
|
||||
}//GEN-LAST:event_btnExportModpackActionPerformed
|
||||
|
||||
private void txtPasswordCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtPasswordCaretUpdate
|
||||
Settings.getInstance().getAuthenticator().setPassword(txtPassword.getText());
|
||||
}//GEN-LAST:event_txtPasswordCaretUpdate
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Loads">
|
||||
private void prepareAuths() {
|
||||
preparingAuth = true;
|
||||
cboLoginMode.removeAllItems();
|
||||
for (IAuthenticator str : AbstractAuthenticator.LOGINS)
|
||||
cboLoginMode.addItem(str.getName());
|
||||
preparingAuth = false;
|
||||
int loginType = Settings.getInstance().getLoginType();
|
||||
if (0 <= loginType && loginType < cboLoginMode.getItemCount()) {
|
||||
cboLoginMode.setSelectedIndex(loginType);
|
||||
Settings.getInstance().setLoginType(loginType);
|
||||
}
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Private Variables">
|
||||
boolean preparingAuth = true;
|
||||
private boolean isLoading = false;
|
||||
private javax.swing.JPanel pnlButtons;
|
||||
private CustomButton btnRun;
|
||||
private static final int DEFAULT_WIDTH = 800, DEFAULT_HEIGHT = 480;
|
||||
//</editor-fold>
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
initGui();
|
||||
super.onCreate();
|
||||
Settings.onProfileLoading();
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnExportModpack;
|
||||
private javax.swing.JButton btnImportModpack;
|
||||
private javax.swing.JButton btnLogout;
|
||||
private javax.swing.JComboBox cboLoginMode;
|
||||
private javax.swing.JComboBox cboProfiles;
|
||||
private javax.swing.JComboBox cboVersions;
|
||||
private javax.swing.JLabel lblLogin;
|
||||
private javax.swing.JLabel lblPassword;
|
||||
private javax.swing.JLabel lblProfile;
|
||||
private javax.swing.JLabel lblUserName;
|
||||
private javax.swing.JLabel lblVersion;
|
||||
private javax.swing.JPanel pnlLogIn;
|
||||
private javax.swing.JPanel pnlLogOut;
|
||||
private javax.swing.JPanel pnlMore;
|
||||
private javax.swing.JPanel pnlPassword;
|
||||
private javax.swing.JPanel pnlRoot;
|
||||
private javax.swing.JPasswordField txtPassword;
|
||||
private javax.swing.JTextField txtPlayerName;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
final Consumer<AuthenticatorChangedEvent> onAuthChanged = (x) -> {
|
||||
if (x.getValue().hasPassword()) {
|
||||
pnlPassword.setVisible(true);
|
||||
lblUserName.setText(C.i18n("login.account"));
|
||||
} else {
|
||||
pnlPassword.setVisible(false);
|
||||
lblUserName.setText(C.i18n("login.username"));
|
||||
}
|
||||
|
||||
CardLayout cl = (CardLayout) pnlPassword.getLayout();
|
||||
if (x.getValue().isLoggedIn())
|
||||
cl.last(pnlPassword);
|
||||
else
|
||||
cl.first(pnlPassword);
|
||||
String username = x.getValue().getUserName();
|
||||
if (username == null)
|
||||
username = "";
|
||||
txtPlayerName.setText(username);
|
||||
};
|
||||
|
||||
final Runnable onLoadingProfiles = () -> {
|
||||
isLoading = true;
|
||||
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
|
||||
for (Profile s : Settings.getProfilesFiltered())
|
||||
model.addElement(s.getName());
|
||||
cboProfiles.setModel(model);
|
||||
isLoading = false;
|
||||
};
|
||||
|
||||
final Consumer<RefreshedVersionsEvent> onRefreshedVersions = t -> {
|
||||
if (Settings.getLastProfile().service().version() == t.getSource())
|
||||
loadVersions();
|
||||
};
|
||||
|
||||
boolean showedNoVersion = false;
|
||||
|
||||
void loadVersions() {
|
||||
isLoading = true;
|
||||
cboVersions.removeAllItems();
|
||||
String selVersion = Settings.getLastProfile().getSelectedVersion();
|
||||
if (!Settings.getLastProfile().service().version().getVersions().isEmpty()) {
|
||||
for (MinecraftVersion mcVersion : Settings.getLastProfile().service().version().getVersions()) {
|
||||
if (mcVersion.hidden)
|
||||
continue;
|
||||
cboVersions.addItem(mcVersion.id);
|
||||
}
|
||||
versionChanged(selVersion);
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
final Consumer<LaunchingStateChangedEvent> launchingStateChanged = t -> SwingUtilities.invokeLater(() -> SwingUtils.setEnabled(MainFrame.INSTANCE.getRootPane(), t.getValue() == LaunchingState.Done));
|
||||
|
||||
void versionChanged(String selectedVersion) {
|
||||
isLoading = true;
|
||||
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboVersions.getModel();
|
||||
for (int i = 0; i < model.getSize(); ++i)
|
||||
if (model.getElementAt(i).equals(selectedVersion)) {
|
||||
model.setSelectedItem(selectedVersion);
|
||||
break;
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
|
||||
Profile t = event.getValue();
|
||||
t.propertyChanged.register(e -> {
|
||||
if ("selectedVersion".equals(e.getPropertyName()))
|
||||
versionChanged(e.getNewValue());
|
||||
});
|
||||
|
||||
isLoading = true;
|
||||
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel();
|
||||
for (int i = 0; i < model.getSize(); ++i)
|
||||
if (model.getElementAt(i).equals(t.getName())) {
|
||||
model.setSelectedItem(t.getName());
|
||||
break;
|
||||
}
|
||||
isLoading = false;
|
||||
};
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.newProfileWindow.title" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtNewProfileName" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="262" max="32767" attributes="0"/>
|
||||
<Component id="btnOK" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtNewProfileName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnOK" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.newProfileWindow.new_profile_name" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtNewProfileName">
|
||||
<Events>
|
||||
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtNewProfileNameKeyTyped"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.label.newProfileWindow.copy_from" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboProfiles">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="button.cancel" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnOK">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="ui.button.ok" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnOKActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class NewProfileWindow extends javax.swing.JDialog {
|
||||
|
||||
public NewProfileWindow(java.awt.Frame parent) {
|
||||
super(parent, true);
|
||||
initComponents();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
for (Profile s : Settings.getProfilesFiltered())
|
||||
cboProfiles.addItem(s.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
txtNewProfileName = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
cboProfiles = new javax.swing.JComboBox();
|
||||
btnCancel = new javax.swing.JButton();
|
||||
btnOK = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(C.i18n("ui.newProfileWindow.title")); // NOI18N
|
||||
|
||||
jLabel1.setText(C.i18n("ui.label.newProfileWindow.new_profile_name")); // NOI18N
|
||||
|
||||
txtNewProfileName.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyTyped(java.awt.event.KeyEvent evt) {
|
||||
txtNewProfileNameKeyTyped(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel2.setText(C.i18n("ui.label.newProfileWindow.copy_from")); // NOI18N
|
||||
|
||||
btnCancel.setText(C.i18n("button.cancel")); // NOI18N
|
||||
btnCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnOK.setText(C.i18n("ui.button.ok")); // NOI18N
|
||||
btnOK.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnOKActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtNewProfileName))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 262, Short.MAX_VALUE)
|
||||
.addComponent(btnOK)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnCancel)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(txtNewProfileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(cboProfiles, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnCancel)
|
||||
.addComponent(btnOK))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void txtNewProfileNameKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtNewProfileNameKeyTyped
|
||||
switch (evt.getKeyCode()) {
|
||||
case 13:
|
||||
act();
|
||||
break;
|
||||
case 27:
|
||||
this.dispose();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}//GEN-LAST:event_txtNewProfileNameKeyTyped
|
||||
|
||||
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
||||
act();
|
||||
}//GEN-LAST:event_btnOKActionPerformed
|
||||
|
||||
void act() {
|
||||
if (!StrUtils.isBlank(txtNewProfileName.getText())) {
|
||||
Profile newProfile = new Profile(txtNewProfileName.getText(), Settings.getProfile(cboProfiles.getSelectedItem().toString()));
|
||||
Settings.putProfile(newProfile);
|
||||
}
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_btnCancelActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCancel;
|
||||
private javax.swing.JButton btnOK;
|
||||
private javax.swing.JComboBox cboProfiles;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JTextField txtNewProfileName;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class NewTabPane extends JTabbedPane implements ChangeListener {
|
||||
|
||||
public NewTabPane() {
|
||||
super();
|
||||
addChangeListener(this);
|
||||
}
|
||||
|
||||
public boolean initializing;
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if (initializing)
|
||||
return;
|
||||
for (int i = 0; i < getComponentCount(); ++i)
|
||||
if (getComponent(i) instanceof TopTabPage) {
|
||||
TopTabPage comp = (TopTabPage) getComponent(i);
|
||||
comp.setId(i);
|
||||
if (getSelectedIndex() != i)
|
||||
((TopTabPage) getComponent(i)).onLeave();
|
||||
}
|
||||
if (getSelectedComponent() instanceof TopTabPage) {
|
||||
if (page == null && getComponentCount() > 0 && getComponent(0) instanceof TopTabPage)
|
||||
page = (TopTabPage) getComponent(0);
|
||||
((TopTabPage) getSelectedComponent()).onSelect(page);
|
||||
page = (TopTabPage) getSelectedComponent();
|
||||
}
|
||||
}
|
||||
|
||||
TopTabPage page = null;
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import org.jackhuang.hmcl.util.ui.IRepaint;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class RepaintPage extends Page implements IRepaint {
|
||||
|
||||
public RepaintPage() {
|
||||
super();
|
||||
}
|
||||
|
||||
JComponent repainter;
|
||||
|
||||
@Override
|
||||
public JComponent getRepaintComponent() {
|
||||
return repainter;
|
||||
}
|
||||
|
||||
public void setRepainter(JComponent repainter) {
|
||||
this.repainter = repainter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Rectangle> getRepaintRects() {
|
||||
return Arrays.asList(this.getBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getRepaintWindow() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblTitle" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblTitle" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="250" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextPane" name="txtDescription">
|
||||
<Events>
|
||||
<EventHandler event="caretUpdate" listener="javax.swing.event.CaretListener" parameters="javax.swing.event.CaretEvent" handler="txtDescriptionCaretUpdate"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="jButton1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="ui.button.preview" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblTitle">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.desc" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.modpack;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.HeadlessException;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.net.WebPage;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardController;
|
||||
import org.markdown4j.Markdown4jProcessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackDescriptionPanel extends javax.swing.JPanel {
|
||||
|
||||
public static final String KEY_MODPACK_DESCRITION = "modpackDescription";
|
||||
|
||||
private final transient WizardController controller;
|
||||
private final Map wizardData;
|
||||
|
||||
/**
|
||||
* Creates new form ModpackDescriptionPanel
|
||||
*/
|
||||
public ModpackDescriptionPanel(WizardController controller, Map wizardData) {
|
||||
initComponents();
|
||||
|
||||
this.controller = controller;
|
||||
this.wizardData = wizardData;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
txtDescription = new javax.swing.JTextPane();
|
||||
jButton1 = new javax.swing.JButton();
|
||||
lblTitle = new javax.swing.JLabel();
|
||||
|
||||
txtDescription.addCaretListener(new javax.swing.event.CaretListener() {
|
||||
public void caretUpdate(javax.swing.event.CaretEvent evt) {
|
||||
txtDescriptionCaretUpdate(evt);
|
||||
}
|
||||
});
|
||||
jScrollPane1.setViewportView(txtDescription);
|
||||
|
||||
jButton1.setText(C.i18n("ui.button.preview")); // NOI18N
|
||||
jButton1.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButton1ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblTitle.setText(C.i18n("modpack.desc")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(jButton1))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblTitle)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblTitle)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jButton1))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void txtDescriptionCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtDescriptionCaretUpdate
|
||||
wizardData.put(KEY_MODPACK_DESCRITION, txtDescription.getText());
|
||||
}//GEN-LAST:event_txtDescriptionCaretUpdate
|
||||
|
||||
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
|
||||
try {
|
||||
Object msgs[] = new Object[2];
|
||||
msgs[0] = C.i18n("ui.button.preview");
|
||||
msgs[1] = new WebPage(new Markdown4jProcessor().process(txtDescription.getText()));
|
||||
((WebPage) msgs[1]).setPreferredSize(new Dimension(800, 350));
|
||||
JOptionPane.showOptionDialog(null, msgs, (String) msgs[0], JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
|
||||
} catch (HeadlessException | IOException e) {
|
||||
MessageBox.show(StrUtils.getStackTrace(e), C.i18n("message.error"), MessageBox.WARNING_MESSAGE);
|
||||
}
|
||||
}//GEN-LAST:event_jButton1ActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton jButton1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel lblTitle;
|
||||
private javax.swing.JTextPane txtDescription;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="1" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTree" name="jTree1">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.modpack;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import org.jackhuang.hmcl.core.mod.ModAdviser;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.ui.checktree.CheckBoxTreeCellRenderer;
|
||||
import org.jackhuang.hmcl.util.ui.checktree.CheckBoxTreeNode;
|
||||
import org.jackhuang.hmcl.util.ui.checktree.CheckBoxTreeNodeSelectionListener;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackFileSelectionPanel extends javax.swing.JPanel {
|
||||
|
||||
private transient final WizardController controller;
|
||||
private final Map wizardData;
|
||||
private transient final ModAdviser blackList;
|
||||
private final Set<String> bannedFiles = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Creates new form ModpackFileSelectionPanel
|
||||
*
|
||||
* @param blackList Return 0: non blocked, 1: non shown, 2: suggested,
|
||||
* checked
|
||||
*/
|
||||
public ModpackFileSelectionPanel(WizardController controller, Map wizardData, File gameDir, ModAdviser blackList) {
|
||||
initComponents();
|
||||
|
||||
this.controller = controller;
|
||||
this.wizardData = wizardData;
|
||||
this.blackList = blackList;
|
||||
|
||||
CheckBoxTreeNode root = create(gameDir, "minecraft");
|
||||
|
||||
jTree1.setModel(new DefaultTreeModel(root));
|
||||
jTree1.setCellRenderer(new CheckBoxTreeCellRenderer());
|
||||
jTree1.addMouseListener(new CheckBoxTreeNodeSelectionListener());
|
||||
|
||||
wizardData.put("blackList", root);
|
||||
}
|
||||
|
||||
private static final HashMap<String, String> TRANSLATION = new HashMap<String, String>() {
|
||||
{
|
||||
put("minecraft/servers.dat", C.i18n("modpack.files.servers_dat"));
|
||||
put("minecraft/saves", C.i18n("modpack.files.saves"));
|
||||
put("minecraft/mods", C.i18n("modpack.files.mods"));
|
||||
put("minecraft/config", C.i18n("modpack.files.config"));
|
||||
put("minecraft/liteconfig", C.i18n("modpack.files.liteconfig"));
|
||||
put("minecraft/resourcepacks", C.i18n("modpack.files.resourcepacks"));
|
||||
put("minecraft/options.txt", C.i18n("modpack.files.options_txt"));
|
||||
put("minecraft/optionsshaders.txt", C.i18n("modpack.files.optionsshaders_txt"));
|
||||
put("minecraft/mods/VoxelMods", C.i18n("modpack.files.mods.voxelmods"));
|
||||
put("minecraft/dumps", C.i18n("modpack.files.dumps"));
|
||||
put("minecraft/blueprints", C.i18n("modpack.files.blueprints"));
|
||||
put("minecraft/scripts", C.i18n("modpack.files.scripts"));
|
||||
}
|
||||
};
|
||||
|
||||
CheckBoxTreeNode create(File file, String basePath) {
|
||||
ModAdviser.ModSuggestion state = ModAdviser.ModSuggestion.NORMAL;
|
||||
if (basePath.length() > "minecraft/".length())
|
||||
if ((state = blackList.advise(basePath.substring("minecraft/".length()) + (file.isDirectory() ? "/" : ""), file.isDirectory())) == ModAdviser.ModSuggestion.HIDDEN)
|
||||
return null;
|
||||
CheckBoxTreeNode node = new CheckBoxTreeNode(TRANSLATION.containsKey(basePath) ? new Pair<>(FileUtils.getName(basePath), TRANSLATION.get(basePath)) : FileUtils.getName(basePath));
|
||||
if (state == ModAdviser.ModSuggestion.SUGGESTED)
|
||||
node.setSelected(true);
|
||||
|
||||
if (file.isDirectory()) {
|
||||
File[] f = file.listFiles();
|
||||
for (File subFile : f) {
|
||||
CheckBoxTreeNode subNode = create(subFile, basePath + "/" + subFile.getName());
|
||||
if (subNode != null) {
|
||||
subNode.setSelected(subNode.isSelected() | node.isSelected());
|
||||
node.add(subNode);
|
||||
}
|
||||
}
|
||||
if (!node.children().hasMoreElements())
|
||||
return null;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jTree1 = new javax.swing.JTree();
|
||||
|
||||
jScrollPane1.setViewportView(jTree1);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JTree jTree1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="txtModpackName" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblModpackLocation" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="353" max="32767" attributes="0"/>
|
||||
<Component id="cboModpackLocation" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="txtModpackLocation" max="32767" attributes="0"/>
|
||||
<Component id="cboGameVersion" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblGameVersion" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkIncludeLauncher" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="19" max="32767" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtModpackName" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblModpackLocation" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboModpackLocation" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtModpackLocation" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblGameVersion" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cboGameVersion" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkIncludeLauncher" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblModpackLocation">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.wizard.step.initialization.save" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtModpackLocation">
|
||||
<Events>
|
||||
<EventHandler event="caretUpdate" listener="javax.swing.event.CaretListener" parameters="javax.swing.event.CaretEvent" handler="txtModpackLocationCaretUpdate"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cboModpackLocation">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="..."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cboModpackLocationActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblGameVersion">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.wizard.step.initialization.exported_version" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboGameVersion">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboGameVersionItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.wizard.step.initialization.warning" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.name" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtModpackName">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="caretUpdate" listener="javax.swing.event.CaretListener" parameters="javax.swing.event.CaretEvent" handler="txtModpackNameCaretUpdate"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkIncludeLauncher">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="modpack.wizard.step.initialization.include_launcher" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkIncludeLauncherItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.modpack;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.ui.JSystemFileChooser;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
|
||||
public static final String KEY_GAME_VERSION = "gameVersion";
|
||||
public static final String KEY_MODPACK_LOCATION = "modpackLocation";
|
||||
public static final String KEY_MODPACK_NAME = "modpackName";
|
||||
public static final String KEY_INCLUDING_LAUNCHER = "launcher";
|
||||
|
||||
private final transient WizardController controller;
|
||||
private final Map<String, Object> wizardData;
|
||||
|
||||
/**
|
||||
* Creates new form ModpackInitializationPanel
|
||||
*/
|
||||
public ModpackInitializationPanel(WizardController controller, Map<String, Object> wizardData, Vector<String> versions, String selVersion) {
|
||||
initComponents();
|
||||
|
||||
this.controller = controller;
|
||||
this.wizardData = wizardData;
|
||||
wizardData.put(KEY_GAME_VERSION, versions);
|
||||
wizardData.put("selVersion", selVersion);
|
||||
wizardData.put(KEY_INCLUDING_LAUNCHER, false);
|
||||
|
||||
configureComboContents();
|
||||
checkProblem();
|
||||
}
|
||||
|
||||
private void configureComboContents() {
|
||||
Vector<String> versions = (Vector<String>) wizardData.get(KEY_GAME_VERSION);
|
||||
cboGameVersion.setModel(new DefaultComboBoxModel<>(versions));
|
||||
wizardData.put(KEY_GAME_VERSION, wizardData.get("selVersion"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
lblModpackLocation = new javax.swing.JLabel();
|
||||
txtModpackLocation = new javax.swing.JTextField();
|
||||
cboModpackLocation = new javax.swing.JButton();
|
||||
lblGameVersion = new javax.swing.JLabel();
|
||||
cboGameVersion = new javax.swing.JComboBox<>();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
txtModpackName = new javax.swing.JTextField();
|
||||
chkIncludeLauncher = new javax.swing.JCheckBox();
|
||||
|
||||
lblModpackLocation.setText(C.i18n("modpack.wizard.step.initialization.save")); // NOI18N
|
||||
|
||||
txtModpackLocation.addCaretListener(new javax.swing.event.CaretListener() {
|
||||
public void caretUpdate(javax.swing.event.CaretEvent evt) {
|
||||
txtModpackLocationCaretUpdate(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cboModpackLocation.setText("...");
|
||||
cboModpackLocation.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cboModpackLocationActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblGameVersion.setText(C.i18n("modpack.wizard.step.initialization.exported_version")); // NOI18N
|
||||
|
||||
cboGameVersion.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboGameVersionItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText(C.i18n("modpack.wizard.step.initialization.warning")); // NOI18N
|
||||
|
||||
jLabel2.setText(C.i18n("modpack.name")); // NOI18N
|
||||
|
||||
txtModpackName.setToolTipText("");
|
||||
txtModpackName.addCaretListener(new javax.swing.event.CaretListener() {
|
||||
public void caretUpdate(javax.swing.event.CaretEvent evt) {
|
||||
txtModpackNameCaretUpdate(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkIncludeLauncher.setText(C.i18n("modpack.wizard.step.initialization.include_launcher")); // NOI18N
|
||||
chkIncludeLauncher.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkIncludeLauncherItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(txtModpackName)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblModpackLocation)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 353, Short.MAX_VALUE)
|
||||
.addComponent(cboModpackLocation))
|
||||
.addComponent(txtModpackLocation)
|
||||
.addComponent(cboGameVersion, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblGameVersion)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(chkIncludeLauncher))
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtModpackName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblModpackLocation)
|
||||
.addComponent(cboModpackLocation))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtModpackLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblGameVersion)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cboGameVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkIncludeLauncher)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void cboModpackLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboModpackLocationActionPerformed
|
||||
JSystemFileChooser fc = new JSystemFileChooser();
|
||||
fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY);
|
||||
fc.setDialogTitle(C.i18n("modpack.wizard.step.initialization.save"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.setFileFilter(new FileNameExtensionFilter(C.i18n("modpack") + "(*.zip)", "zip"));
|
||||
fc.showSaveDialog(this);
|
||||
if (fc.getSelectedFile() != null) {
|
||||
String path = fc.getSelectedFile().getAbsolutePath();
|
||||
if (!path.endsWith(".zip"))
|
||||
path += ".zip";
|
||||
txtModpackLocation.setText(path);
|
||||
}
|
||||
}//GEN-LAST:event_cboModpackLocationActionPerformed
|
||||
|
||||
private void txtModpackLocationCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtModpackLocationCaretUpdate
|
||||
wizardData.put(KEY_MODPACK_LOCATION, txtModpackLocation.getText());
|
||||
|
||||
checkProblem();
|
||||
}//GEN-LAST:event_txtModpackLocationCaretUpdate
|
||||
|
||||
private void cboGameVersionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboGameVersionItemStateChanged
|
||||
wizardData.put(KEY_GAME_VERSION, cboGameVersion.getSelectedItem());
|
||||
}//GEN-LAST:event_cboGameVersionItemStateChanged
|
||||
|
||||
private void txtModpackNameCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtModpackNameCaretUpdate
|
||||
wizardData.put(KEY_MODPACK_NAME, txtModpackName.getText());
|
||||
|
||||
checkProblem();
|
||||
}//GEN-LAST:event_txtModpackNameCaretUpdate
|
||||
|
||||
private void chkIncludeLauncherItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkIncludeLauncherItemStateChanged
|
||||
wizardData.put(KEY_INCLUDING_LAUNCHER, chkIncludeLauncher.isSelected());
|
||||
}//GEN-LAST:event_chkIncludeLauncherItemStateChanged
|
||||
|
||||
static final Pattern PATTERN = Pattern.compile("[-a-zA-Z0-9_\\.\\(\\)\\[\\]\\{\\}\\<\\>\"\'\u4E00-\u9FA5]+$");
|
||||
|
||||
void checkProblem() {
|
||||
controller.setProblem(null);
|
||||
if (txtModpackLocation.getText().trim().isEmpty())
|
||||
controller.setProblem(C.i18n("modpack.not_a_valid_location"));
|
||||
if (!PATTERN.matcher(txtModpackName.getText()).matches())
|
||||
controller.setProblem(C.i18n("modpack.not_a_valid_name"));
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JComboBox<String> cboGameVersion;
|
||||
private javax.swing.JButton cboModpackLocation;
|
||||
private javax.swing.JCheckBox chkIncludeLauncher;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel lblGameVersion;
|
||||
private javax.swing.JLabel lblModpackLocation;
|
||||
private javax.swing.JTextField txtModpackLocation;
|
||||
private javax.swing.JTextField txtModpackName;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.modpack;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import javax.swing.JComponent;
|
||||
import org.jackhuang.hmcl.core.GameException;
|
||||
import org.jackhuang.hmcl.core.mod.ModpackManager;
|
||||
import org.jackhuang.hmcl.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hmcl.setting.Config;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.HMCLMinecraftService;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.Utils;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
import org.jackhuang.hmcl.util.sys.ZipEngine;
|
||||
import org.jackhuang.hmcl.util.net.WebPage;
|
||||
import org.jackhuang.hmcl.util.ui.checktree.CheckBoxTreeNode;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.DeferredWizardResult;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.ResultProgressHandle;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.Summary;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardBranchController;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardController;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardException;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.spi.WizardPanelProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackWizard extends WizardBranchController {
|
||||
|
||||
static void process(CheckBoxTreeNode node, String basePath, List<String> list) {
|
||||
if (node == null)
|
||||
return;
|
||||
if (node.isSelected()) {
|
||||
if (basePath.length() > "minecraft/".length())
|
||||
list.add(basePath.substring("minecraft/".length()));
|
||||
return;
|
||||
}
|
||||
Enumeration<CheckBoxTreeNode> e = node.children();
|
||||
for (; e.hasMoreElements();) {
|
||||
CheckBoxTreeNode n = e.nextElement();
|
||||
String s;
|
||||
if (n.getUserObject() instanceof Pair)
|
||||
s = ((Pair<String, String>) n.getUserObject()).key;
|
||||
else
|
||||
s = n.getUserObject().toString();
|
||||
process(n, basePath + "/" + s, list);
|
||||
}
|
||||
}
|
||||
|
||||
public ModpackWizard(Profile profile) {
|
||||
super(new WizardPanelProvider(C.i18n("modpack.wizard"), new String[] { C.i18n("modpack.wizard.step.1"), C.i18n("modpack.wizard.step.2"), C.i18n("modpack.wizard.step.3") }, new String[] { C.i18n("modpack.wizard.step.1.title"), C.i18n("modpack.wizard.step.2.title"), C.i18n("modpack.wizard.step.3.title") }) {
|
||||
|
||||
@Override
|
||||
protected Object finish(Map settings) throws WizardException {
|
||||
return new DeferredWizardResult(false) {
|
||||
@Override
|
||||
public void start(Map settings, ResultProgressHandle progress) {
|
||||
progress.setBusy("Processing modpack");
|
||||
ArrayList<String> blackList = new ArrayList<>(ModpackManager.MODPACK_BLACK_LIST);
|
||||
CheckBoxTreeNode root = (CheckBoxTreeNode) settings.get("blackList");
|
||||
process(root, "minecraft", blackList);
|
||||
HashMap map = new HashMap();
|
||||
map.put("name", (String) settings.get(ModpackInitializationPanel.KEY_MODPACK_NAME));
|
||||
|
||||
if (settings.containsKey(ModpackDescriptionPanel.KEY_MODPACK_DESCRITION))
|
||||
try {
|
||||
map.put("description", new org.markdown4j.Markdown4jProcessor().process((String) settings.get(ModpackDescriptionPanel.KEY_MODPACK_DESCRITION)));
|
||||
} catch (IOException ex) {
|
||||
progress.failed(C.i18n("modpack.export_error") + ": " + StrUtils.getStackTrace(ex), true);
|
||||
}
|
||||
try {
|
||||
String gameVersion = (String) settings.get(ModpackInitializationPanel.KEY_GAME_VERSION);
|
||||
String strLocation = (String) settings.get(ModpackInitializationPanel.KEY_MODPACK_LOCATION);
|
||||
if (!strLocation.endsWith(".zip"))
|
||||
strLocation += ".zip";
|
||||
File loc = new File(strLocation);
|
||||
File modpack = loc;
|
||||
if ((Boolean) settings.get(ModpackInitializationPanel.KEY_INCLUDING_LAUNCHER))
|
||||
modpack = new File(loc.getAbsolutePath() + ".temp");
|
||||
ModpackManager.export(modpack, profile.service().version(), gameVersion, blackList, map,
|
||||
t -> t.putTextFile(C.GSON.toJson(((HMCLMinecraftService) profile.service()).getVersionSetting(gameVersion)), "minecraft/hmclversion.cfg"));
|
||||
String summary = "<html>" + C.i18n("modpack.export_finished") + ": " + loc.getAbsolutePath();
|
||||
boolean including = false;
|
||||
if ((Boolean) settings.get(ModpackInitializationPanel.KEY_INCLUDING_LAUNCHER)) {
|
||||
boolean flag = true;
|
||||
try (ZipEngine engine = new ZipEngine(loc)) {
|
||||
Config s = new Config();
|
||||
if (!IOUtils.isAbsolutePath(Settings.getInstance().getBgpath()))
|
||||
s.setBgpath(Settings.getInstance().getBgpath());
|
||||
s.setDownloadType(Settings.getInstance().getDownloadType());
|
||||
engine.putTextFile(C.GSON.toJson(s), "hmcl.json");
|
||||
engine.putFile(modpack, "modpack.zip");
|
||||
File bg = new File("bg").getAbsoluteFile();
|
||||
if (bg.isDirectory())
|
||||
engine.putDirectory(bg);
|
||||
bg = new File("background.png").getAbsoluteFile();
|
||||
if (bg.isFile())
|
||||
engine.putFile(bg, "background.png");
|
||||
bg = new File("background.jpg").getAbsoluteFile();
|
||||
if (bg.isFile())
|
||||
engine.putFile(bg, "background.jpg");
|
||||
for (URL u : Utils.getURL())
|
||||
try {
|
||||
File f = new File(u.toURI());
|
||||
if (f.getName().endsWith(".exe") || f.getName().endsWith(".jar"))
|
||||
engine.putFile(f, f.getName());
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
HMCLog.err("Failed to add launcher files.", e);
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
including = true;
|
||||
if (!modpack.delete())
|
||||
HMCLog.warn("Failed to delete modpack.zip.temp, maybe the file is in using.");
|
||||
}
|
||||
}
|
||||
summary += "<br/>" + C.i18n(including ? "modpack.included_launcher" : "modpack.not_included_launcher") + "</html>";
|
||||
progress.finished(new Summary(new WebPage(summary), null));
|
||||
} catch (IOException | GameException ex) {
|
||||
HMCLog.err("Failed to export modpack", ex);
|
||||
progress.failed(C.i18n("modpack.export_error") + ": " + StrUtils.getStackTrace(ex), true);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
protected JComponent createPanel(WizardController controller, String id, Map settings) {
|
||||
switch (indexOfStep(id)) {
|
||||
case 0:
|
||||
Vector<String> s = new Vector<>(profile.service().version().getVersionCount());
|
||||
for (MinecraftVersion v : profile.service().version().getVersions())
|
||||
if (!v.hidden)
|
||||
s.add(v.id);
|
||||
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_CONTINUE);
|
||||
|
||||
return new ModpackInitializationPanel(controller, settings, s, profile.getSelectedVersion());
|
||||
case 1:
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_CONTINUE_OR_FINISH);
|
||||
|
||||
return new ModpackFileSelectionPanel(controller, settings, profile.service().baseDirectory(), ModpackManager.MODPACK_PREDICATE);
|
||||
case 2:
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_FINISH);
|
||||
|
||||
return new ModpackDescriptionPanel(controller, settings);
|
||||
default:
|
||||
throw new IllegalArgumentException(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WizardPanelProvider getPanelProviderForStep(String step, Map settings) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import static org.jackhuang.hmcl.Main.LAUNCHER_VERSION;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.net.NetUtils;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
import org.jackhuang.hmcl.ui.LogWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CrashReporter.class.getName());
|
||||
|
||||
private static final HashMap<String, String> SOURCE = new HashMap<String, String>() {
|
||||
{
|
||||
put("MessageBox", "");
|
||||
put("AWTError", "");
|
||||
put("JFileChooser", "Has your operating system been installed completely or is a ghost system?");
|
||||
put("JSystemFileChooser", "Has your operating system been installed completely or is a ghost system?");
|
||||
put("Jce", "Has your operating system been installed completely or is a ghost system?");
|
||||
put("couldn't create component peer", "Fucking computer!");
|
||||
put("sun.awt.shell.Win32ShellFolder2", "crash.user_fault");
|
||||
put("UnsatisfiedLinkError", "crash.user_fault");
|
||||
put("java.awt.HeadlessException", "crash.headless");
|
||||
put("java.lang.NoClassDefFoundError", "crash.NoClassDefFound");
|
||||
put("java.lang.VerifyError", "crash.NoClassDefFound");
|
||||
put("java.lang.NoSuchMethodError", "crash.NoClassDefFound");
|
||||
put("java.lang.IncompatibleClassChangeError", "crash.NoClassDefFound");
|
||||
put("java.lang.ClassFormatError", "crash.NoClassDefFound");
|
||||
put("java.lang.OutOfMemoryError", "FUCKING MEMORY LIMIT!");
|
||||
put("Trampoline", "ui.message.update_java");
|
||||
put("NoSuchAlgorithmException", "Has your operating system been installed completely or is a ghost system?");
|
||||
}
|
||||
};
|
||||
|
||||
boolean enableLogger = false;
|
||||
|
||||
public CrashReporter(boolean enableLogger) {
|
||||
this.enableLogger = enableLogger;
|
||||
}
|
||||
|
||||
public boolean checkThrowable(Throwable e) {
|
||||
String s = StrUtils.getStackTrace(e);
|
||||
for (HashMap.Entry<String, String> entry : SOURCE.entrySet())
|
||||
if (s.contains(entry.getKey())) {
|
||||
if (StrUtils.isNotBlank(entry.getValue())) {
|
||||
String info = C.i18n(entry.getKey());
|
||||
LOGGER.severe(info);
|
||||
try {
|
||||
showMessage(info);
|
||||
} catch (Throwable t) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to show message", t);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
String s = StrUtils.getStackTrace(e);
|
||||
if (!s.contains("org.jackhuang"))
|
||||
return;
|
||||
try {
|
||||
String text = "\n---- Hello Minecraft! Crash Report ----\n";
|
||||
text += " Version: " + LAUNCHER_VERSION + "\n";
|
||||
text += " Time: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n";
|
||||
text += " Thread: " + t.toString() + "\n";
|
||||
text += "\n Content: \n ";
|
||||
text += s + "\n\n";
|
||||
text += "-- System Details --\n";
|
||||
text += " Operating System: " + OS.getSystemVersion() + "\n";
|
||||
text += " Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor") + "\n";
|
||||
text += " Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor") + "\n";
|
||||
if (enableLogger)
|
||||
HMCLog.err(text);
|
||||
else
|
||||
System.out.println(text);
|
||||
|
||||
if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) {
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.isOutOfDate()));
|
||||
if (!Settings.UPDATE_CHECKER.isOutOfDate())
|
||||
reportToServer(text, s);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to caught exception", ex);
|
||||
LOGGER.log(Level.SEVERE, "There is the original exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
void showMessage(String s) {
|
||||
try {
|
||||
MessageBox.show(s, "ERROR", MessageBox.ERROR_MESSAGE);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.log(Level.SEVERE, "ERROR", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final HashSet<String> THROWABLE_SET = new HashSet<>();
|
||||
|
||||
void reportToServer(final String text, String stacktrace) {
|
||||
if (THROWABLE_SET.contains(stacktrace) || stacktrace.contains("Font") || stacktrace.contains("InternalError"))
|
||||
return;
|
||||
THROWABLE_SET.add(stacktrace);
|
||||
Thread t = new Thread(() -> {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("CrashReport", text);
|
||||
try {
|
||||
NetUtils.post(NetUtils.constantURL("http://huangyuhui.duapp.com/crash.php"), map);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to post HMCL server.", ex);
|
||||
}
|
||||
});
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JFrame;
|
||||
import org.jackhuang.hmcl.api.ui.AddTabCallback;
|
||||
import org.jackhuang.hmcl.api.IPlugin;
|
||||
import org.jackhuang.hmcl.core.auth.OfflineAuthenticator;
|
||||
import org.jackhuang.hmcl.core.auth.YggdrasilAuthenticator;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.ui.GameSettingsPanel;
|
||||
import org.jackhuang.hmcl.ui.LauncherSettingsPanel;
|
||||
import org.jackhuang.hmcl.ui.MainPagePanel;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.api.ui.Theme;
|
||||
import org.jackhuang.hmcl.laf.LAFTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DefaultPlugin implements IPlugin {
|
||||
public static DefaultPlugin INSTANCE;
|
||||
|
||||
public DefaultPlugin() {
|
||||
INSTANCE = this;
|
||||
for (Theme t : LAFTheme.THEMES)
|
||||
Theme.THEMES.put(t.getId(), t);
|
||||
}
|
||||
|
||||
ArrayList<IAuthenticator> auths = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onRegisterAuthenticators(Consumer<IAuthenticator> apply) {
|
||||
String clientToken = Settings.getInstance().getClientToken();
|
||||
auths.add(new OfflineAuthenticator(clientToken));
|
||||
auths.add(new YggdrasilAuthenticator(clientToken));
|
||||
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::saveAuthenticatorConfig));
|
||||
} catch (IllegalStateException ignore) { // Shutdown in progress
|
||||
}
|
||||
for (IAuthenticator i : auths) {
|
||||
i.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(i.id()));
|
||||
apply.accept(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAuthenticatorConfig() {
|
||||
for (IAuthenticator i : auths)
|
||||
Settings.getInstance().setAuthenticatorConfig(i.id(), i.onSaveSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddTab(JFrame frame, AddTabCallback callback) {
|
||||
callback.addTab(new MainPagePanel(), "main", C.i18n("launcher.title.main"));
|
||||
callback.addTab(new GameSettingsPanel(), "game", C.i18n("launcher.title.game"));
|
||||
callback.addTab(new LauncherSettingsPanel(), "launcher", C.i18n("launcher.title.launcher"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.io.File;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class FileNameFilter extends FileFilter {
|
||||
|
||||
String acceptedName;
|
||||
|
||||
public FileNameFilter(String acceptedName) {
|
||||
this.acceptedName = acceptedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.isDirectory() || f.getName().equals(acceptedName) && !FileUtils.getExtension(f.getName()).equals("lnk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return acceptedName;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hmcl.core.asset.MinecraftAssetService;
|
||||
import org.jackhuang.hmcl.core.service.IMinecraftService;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class HMCLAssetService extends MinecraftAssetService {
|
||||
|
||||
public HMCLAssetService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
private boolean useSelf(String assetId) {
|
||||
return new File(service.baseDirectory(), "assets/indexes/" + assetId + ".json").exists() || ((HMCLMinecraftService) service).getProfile().isNoCommon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssets(String assetId) {
|
||||
if (useSelf(assetId))
|
||||
return new File(service.baseDirectory(), "assets");
|
||||
else
|
||||
return new File(Settings.getInstance().getCommonpath(), "assets");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import org.jackhuang.hmcl.core.GameException;
|
||||
import org.jackhuang.hmcl.api.auth.AuthenticationException;
|
||||
import org.jackhuang.hmcl.core.auth.AbstractAuthenticator;
|
||||
import org.jackhuang.hmcl.api.auth.LoginInfo;
|
||||
import org.jackhuang.hmcl.core.launch.DefaultGameLauncher;
|
||||
import org.jackhuang.hmcl.core.launch.GameLauncher;
|
||||
import org.jackhuang.hmcl.api.game.LaunchOptions;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchSucceededEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingState;
|
||||
import org.jackhuang.hmcl.api.event.launch.LaunchingStateChangedEvent;
|
||||
import org.jackhuang.hmcl.api.event.launch.ProcessingLaunchOptionsEvent;
|
||||
import org.jackhuang.hmcl.core.RuntimeGameException;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.Wrapper;
|
||||
import org.jackhuang.hmcl.util.sys.JavaProcess;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HMCLGameLauncher {
|
||||
|
||||
Profile profile;
|
||||
boolean isLaunching = false;
|
||||
|
||||
public HMCLGameLauncher(Profile p) {
|
||||
this.profile = p;
|
||||
|
||||
HMCLApi.EVENT_BUS.channel(LaunchSucceededEvent.class).register(() -> setLaunching(false));
|
||||
}
|
||||
|
||||
void setLaunching(boolean isLaunching) {
|
||||
if (isLaunching != this.isLaunching)
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, isLaunching ? LaunchingState.Starting : LaunchingState.Done));
|
||||
this.isLaunching = isLaunching;
|
||||
}
|
||||
|
||||
public void genLaunchCode(final Consumer<GameLauncher> listener, final Consumer<String> failed, String passwordIfNeeded) {
|
||||
if (isLaunching || profile == null)
|
||||
return;
|
||||
setLaunching(true);
|
||||
HMCLog.log("Start generating launching command...");
|
||||
if (!profile.getGameDir().exists()) {
|
||||
failed.accept(C.i18n("minecraft.wrong_path"));
|
||||
setLaunching(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile.getSelectedVersion() == null) {
|
||||
failed.accept(C.i18n("minecraft.no_selected_version"));
|
||||
setLaunching(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final IAuthenticator l = AbstractAuthenticator.LOGINS.get(Settings.getInstance().getLoginType());
|
||||
final LoginInfo li = new LoginInfo(l.getUserName(), l.isLoggedIn() || !l.hasPassword() ? null : passwordIfNeeded);
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("Game Launcher");
|
||||
try {
|
||||
Wrapper<LaunchOptions> options = new Wrapper<>(profile.getSelectedVersionSetting().createLaunchOptions(profile.getGameDir()));
|
||||
HMCLApi.EVENT_BUS.fireChannel(new ProcessingLaunchOptionsEvent(this, options));
|
||||
DefaultGameLauncher gl = new DefaultGameLauncher(options.getValue(), profile.service(), li, l);
|
||||
GameLauncherTag tag = new GameLauncherTag();
|
||||
tag.launcherVisibility = profile.getSelectedVersionSetting().getLauncherVisibility();
|
||||
gl.setTag(tag);
|
||||
listener.accept(gl);
|
||||
gl.makeLaunchCommand();
|
||||
} catch (GameException | RuntimeGameException e) {
|
||||
failed.accept(C.i18n("launch.failed") + ", " + e.getMessage());
|
||||
setLaunching(false);
|
||||
} catch (AuthenticationException e) {
|
||||
failed.accept(C.i18n("login.failed") + ", " + e.getMessage());
|
||||
setLaunching(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static class GameLauncherTag {
|
||||
public LauncherVisibility launcherVisibility;
|
||||
public JavaProcess process;
|
||||
public int state; // 0 - unknown; 1 - launch; 2 - make launch script.
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hmcl.api.game.GameDirType;
|
||||
import org.jackhuang.hmcl.api.game.IMinecraftLibrary;
|
||||
import org.jackhuang.hmcl.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hmcl.core.version.MinecraftVersionManager;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HMCLGameProvider extends MinecraftVersionManager<HMCLMinecraftService> {
|
||||
|
||||
public HMCLGameProvider(HMCLMinecraftService p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getLibraryFile(MinecraftVersion version, IMinecraftLibrary lib) {
|
||||
VersionSetting vs = service.getProfile().getVersionSetting(version.id);
|
||||
File self = super.getLibraryFile(version, lib);
|
||||
if (self.exists() || (vs != null && service.getProfile().isNoCommon()))
|
||||
return self;
|
||||
else
|
||||
return lib.getFilePath(new File(Settings.getInstance().getCommonpath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRunDirectory(String id) {
|
||||
VersionSetting vs = service.getProfile().getVersionSetting(id);
|
||||
if (vs == null)
|
||||
return super.getRunDirectory(id);
|
||||
else
|
||||
return vs.getGameDirType() == GameDirType.VERSION_FOLDER
|
||||
? service.version().versionRoot(id)
|
||||
: super.getRunDirectory(id);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.util.List;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.auth.UserProfileProvider;
|
||||
import org.jackhuang.hmcl.api.game.LaunchOptions;
|
||||
import org.jackhuang.hmcl.core.GameException;
|
||||
import org.jackhuang.hmcl.core.launch.MinecraftLoader;
|
||||
import org.jackhuang.hmcl.core.service.IMinecraftService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class HMCLMinecraftLoader extends MinecraftLoader {
|
||||
|
||||
public HMCLMinecraftLoader(LaunchOptions p, IMinecraftService provider, UserProfileProvider lr) throws GameException {
|
||||
super(p, provider, lr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendJVMArgs(List<String> list) {
|
||||
super.appendJVMArgs(list);
|
||||
|
||||
list.add("-Dminecraft.launcher.version=" + Main.LAUNCHER_VERSION);
|
||||
list.add("-Dminecraft.launcher.brand=" + Main.LAUNCHER_NAME);
|
||||
|
||||
boolean flag = false;
|
||||
for (String s : list) if (s.contains("-Dlog4j.configurationFile=")) flag = true;
|
||||
if (!flag) {
|
||||
list.add("-Dlog4j.configurationFile=" + Main.LOG4J_FILE.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import org.jackhuang.hmcl.core.service.IMinecraftService;
|
||||
import org.jackhuang.hmcl.core.service.IMinecraftLoader;
|
||||
import org.jackhuang.hmcl.core.service.IMinecraftModService;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.version.LoadedOneVersionEvent;
|
||||
import org.jackhuang.hmcl.api.event.version.RefreshedVersionsEvent;
|
||||
import org.jackhuang.hmcl.api.event.version.RefreshingVersionsEvent;
|
||||
import org.jackhuang.hmcl.core.GameException;
|
||||
import org.jackhuang.hmcl.core.install.MinecraftInstallerService;
|
||||
import org.jackhuang.hmcl.api.auth.UserProfileProvider;
|
||||
import org.jackhuang.hmcl.core.download.MinecraftDownloadService;
|
||||
import org.jackhuang.hmcl.api.game.LaunchOptions;
|
||||
import org.jackhuang.hmcl.core.launch.MinecraftLoader;
|
||||
import org.jackhuang.hmcl.core.mod.MinecraftModService;
|
||||
import org.jackhuang.hmcl.core.mod.ModpackManager;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.ui.MainFrame;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HMCLMinecraftService extends IMinecraftService {
|
||||
|
||||
private Profile p;
|
||||
final Map<String, VersionSetting> versionSettings = new HashMap<>();
|
||||
|
||||
public HMCLMinecraftService(Profile p) {
|
||||
this.p = p;
|
||||
this.provider = new HMCLGameProvider(this);
|
||||
provider.initializeMinecraft();
|
||||
HMCLApi.EVENT_BUS.channel(RefreshingVersionsEvent.class).register(versionSettings::clear);
|
||||
HMCLApi.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerFirst(() -> {
|
||||
if (!checkingModpack) {
|
||||
checkingModpack = true;
|
||||
if (version().getVersionCount() == 0) {
|
||||
File modpack = new File("modpack.zip").getAbsoluteFile();
|
||||
if (modpack.exists())
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (TaskWindow.factory().execute(ModpackManager.install(MainFrame.INSTANCE, modpack, this, null)))
|
||||
version().refreshVersions();
|
||||
checkedModpack = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
HMCLApi.EVENT_BUS.channel(LoadedOneVersionEvent.class).register(e -> loadVersionSetting(e.getValue()));
|
||||
this.mms = new MinecraftModService(this);
|
||||
this.mds = new MinecraftDownloadService(this);
|
||||
this.mas = new HMCLAssetService(this);
|
||||
this.mis = new MinecraftInstallerService(this);
|
||||
}
|
||||
|
||||
public boolean checkedModpack = false, checkingModpack = false;
|
||||
|
||||
private void loadVersionSetting(String id) {
|
||||
if (provider.getVersionById(id) == null)
|
||||
return;
|
||||
VersionSetting vs = null;
|
||||
File f = new File(provider.versionRoot(id), "hmclversion.cfg");
|
||||
if (f.exists()) {
|
||||
String s = FileUtils.readQuietly(f);
|
||||
if (s != null)
|
||||
try {
|
||||
vs = C.GSON.fromJson(s, VersionSetting.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
HMCLog.warn("Failed to load version setting: " + id, ex);
|
||||
vs = null;
|
||||
}
|
||||
}
|
||||
if (vs == null)
|
||||
return;
|
||||
initVersionSetting(id, vs);
|
||||
}
|
||||
|
||||
public void createVersionSetting(String id) {
|
||||
if (provider.getVersionById(id) == null || versionSettings.containsKey(id))
|
||||
return;
|
||||
initVersionSetting(id, new VersionSetting());
|
||||
}
|
||||
|
||||
private void initVersionSetting(String id, VersionSetting vs) {
|
||||
vs.id = id;
|
||||
vs.propertyChanged.register(event -> saveVersionSetting(((VersionSetting) event.getSource()).id));
|
||||
versionSettings.put(id, vs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version setting for version id.
|
||||
*
|
||||
* @param id version id
|
||||
*
|
||||
* @return may return null if the id not exists
|
||||
*/
|
||||
public VersionSetting getVersionSetting(String id) {
|
||||
if (!versionSettings.containsKey(id))
|
||||
loadVersionSetting(id);
|
||||
return versionSettings.get(id);
|
||||
}
|
||||
|
||||
public void saveVersionSetting(String id) {
|
||||
if (!versionSettings.containsKey(id))
|
||||
return;
|
||||
File f = new File(provider.versionRoot(id), "hmclversion.cfg");
|
||||
FileUtils.writeQuietly(f, C.GSON.toJson(versionSettings.get(id)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File baseDirectory() {
|
||||
return p.getGameDir();
|
||||
}
|
||||
|
||||
protected HMCLGameProvider provider;
|
||||
|
||||
@Override
|
||||
public HMCLGameProvider version() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
protected MinecraftModService mms;
|
||||
|
||||
@Override
|
||||
public IMinecraftModService mod() {
|
||||
return mms;
|
||||
}
|
||||
|
||||
protected MinecraftDownloadService mds;
|
||||
|
||||
@Override
|
||||
public MinecraftDownloadService download() {
|
||||
return mds;
|
||||
}
|
||||
|
||||
final HMCLAssetService mas;
|
||||
|
||||
@Override
|
||||
public HMCLAssetService asset() {
|
||||
return mas;
|
||||
}
|
||||
|
||||
protected MinecraftInstallerService mis;
|
||||
|
||||
@Override
|
||||
public MinecraftInstallerService install() {
|
||||
return mis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMinecraftLoader launch(LaunchOptions options, UserProfileProvider p) throws GameException {
|
||||
MinecraftLoader l = new HMCLMinecraftLoader(options, this, p);
|
||||
l.setAssetProvider(mas.ASSET_PROVIDER_IMPL);
|
||||
return l;
|
||||
}
|
||||
|
||||
public Profile getProfile() {
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum LauncherVisibility {
|
||||
|
||||
/**
|
||||
* Close the launcher anyway when the game process created even if failed to
|
||||
* launch game.
|
||||
*/
|
||||
CLOSE,
|
||||
/**
|
||||
* Hide the launcher when the game process created, if failed to launch
|
||||
* game, will show the log window.
|
||||
*/
|
||||
HIDE,
|
||||
/**
|
||||
* Keep the launcher visible even if the game launched successfully.
|
||||
*/
|
||||
KEEP,
|
||||
/**
|
||||
* Hide the launcher and reopen it when game closes.
|
||||
*/
|
||||
HIDE_AND_REOPEN
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.process.JavaProcessStoppedEvent;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.ui.LogWindow;
|
||||
import org.jackhuang.hmcl.util.log.Level;
|
||||
import org.jackhuang.hmcl.util.sys.ProcessMonitor;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class Log4jHandler extends Thread implements Consumer<JavaProcessStoppedEvent> {
|
||||
|
||||
XMLReader reader;
|
||||
ProcessMonitor monitor;
|
||||
PipedInputStream inputStream;
|
||||
PipedOutputStream outputStream;
|
||||
List<Pair<String, String>> forbiddenTokens = new LinkedList<>();
|
||||
|
||||
public Log4jHandler(ProcessMonitor monitor, PipedOutputStream outputStream) throws ParserConfigurationException, IOException, SAXException {
|
||||
reader = XMLReaderFactory.createXMLReader();
|
||||
inputStream = new PipedInputStream(outputStream);
|
||||
this.outputStream = outputStream;
|
||||
this.monitor = monitor;
|
||||
|
||||
HMCLApi.EVENT_BUS.channel(JavaProcessStoppedEvent.class).register((Consumer<JavaProcessStoppedEvent>) this);
|
||||
}
|
||||
|
||||
public void addForbiddenToken(String token, String replacement) {
|
||||
forbiddenTokens.add(new Pair<>(token, replacement));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
outputStream.write("<output>".getBytes());
|
||||
outputStream.flush();
|
||||
reader.setContentHandler(new Log4jHandlerImpl());
|
||||
reader.parse(new InputSource(inputStream));
|
||||
} catch (SAXException | IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JavaProcessStoppedEvent t) {
|
||||
if (t.getSource() == monitor) {
|
||||
try {
|
||||
outputStream.write("</output>".getBytes());
|
||||
outputStream.close();
|
||||
} catch (IOException ignore) { // won't happen
|
||||
throw new Error(ignore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Log4jHandlerImpl extends DefaultHandler {
|
||||
private final SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
|
||||
|
||||
String date = "", thread = "", logger = "";
|
||||
StringBuilder message = null;
|
||||
Level l = null;
|
||||
boolean readingMessage = false;
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
switch (localName) {
|
||||
case "log4j_Event":
|
||||
message = new StringBuilder();
|
||||
Date d = new Date(Long.valueOf(attributes.getValue("timestamp")));
|
||||
date = df.format(d);
|
||||
try {
|
||||
l = Level.valueOf(attributes.getValue("level"));
|
||||
} catch(IllegalArgumentException e) {
|
||||
l = Level.INFO;
|
||||
}
|
||||
thread = attributes.getValue("thread");
|
||||
logger = attributes.getValue("logger");
|
||||
if ("STDERR".equals(logger))
|
||||
l = Level.ERROR;
|
||||
break;
|
||||
case "log4j_Message":
|
||||
readingMessage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
switch (localName) {
|
||||
case "log4j_Event":
|
||||
println("[" + date + "] [" + thread + "/" + l.name() + "] [" + logger + "] " + message.toString(), l);
|
||||
break;
|
||||
case "log4j_Message":
|
||||
readingMessage = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
String line = new String(ch, start, length);
|
||||
if (line.trim().isEmpty()) return;
|
||||
if (readingMessage)
|
||||
message.append(line).append(C.LINE_SEPARATOR);
|
||||
else
|
||||
println(line, Level.guessLevel(line));
|
||||
}
|
||||
|
||||
public void println(String message, Level l) {
|
||||
for (Pair<String, String> entry : forbiddenTokens)
|
||||
message = message.replace(entry.key, entry.value);
|
||||
if (LogWindow.outputStream != null)
|
||||
LogWindow.outputStream.log(message, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import org.jackhuang.hmcl.util.lang.SupportedLocales;
|
||||
|
||||
/**
|
||||
* Give the advice to solve the Minecraft crashing.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class MinecraftCrashAdvicer {
|
||||
|
||||
public static String getAdvice(String trace) {
|
||||
return getAdvice(trace, false);
|
||||
}
|
||||
|
||||
public static String getAdvice(String trace, boolean selfCrash) {
|
||||
if (trace == null)
|
||||
return C.i18n("crash.advice.no");
|
||||
trace = trace.toLowerCase(SupportedLocales.getNowLocale().self);
|
||||
if (trace.contains("pixel format not accelerated"))
|
||||
return C.i18n("crash.advice.LWJGLException");
|
||||
else if (trace.contains("unsupportedclassversionrrror"))
|
||||
return C.i18n("crash.advice.UnsupportedClassVersionError");
|
||||
else if (trace.contains("concurrentmodificationexception"))
|
||||
return C.i18n("crash.advice.ConcurrentModificationException");
|
||||
else if (trace.contains("securityexception"))
|
||||
return C.i18n("crash.advice.SecurityException");
|
||||
else if (trace.contains("nosuchfieldexception") || trace.contains("nosuchmethodexception") || trace.contains("nosuchfielderror") || trace.contains("nosuchmethoderror"))
|
||||
return C.i18n("crash.advice.NoSuchFieldError");
|
||||
else if (trace.contains("outofmemory") || trace.contains("out of memory"))
|
||||
return C.i18n("crash.advice.OutOfMemoryError");
|
||||
else if (trace.contains("noclassdeffounderror") || trace.contains("classnotfoundexception"))
|
||||
return C.i18n("crash.advice.ClassNotFoundException");
|
||||
else if (trace.contains("no lwjgl in java.library.path"))
|
||||
return C.i18n("crash.advice.no_lwjgl");
|
||||
else if (trace.contains("opengl") || trace.contains("openal"))
|
||||
return C.i18n("crash.advice.OpenGL");
|
||||
return C.i18n(selfCrash ? "crash.advice.no" : "crash.advice.otherwise");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.upgrade;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Pack200;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.core.MCUtils;
|
||||
import org.jackhuang.hmcl.util.task.Task;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
import org.jackhuang.hmcl.util.net.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.util.ArrayUtils;
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.util.UpdateChecker;
|
||||
import org.jackhuang.hmcl.util.Utils;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AppDataUpgrader extends IUpgrader {
|
||||
|
||||
private boolean launchNewerVersion(String[] args, File jar) throws IOException, PrivilegedActionException {
|
||||
try (JarFile jarFile = new JarFile(jar)) {
|
||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
if (mainClass != null) {
|
||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
||||
al.add("--noupdate");
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
new URLClassLoader(new URL[] { jar.toURI().toURL() },
|
||||
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
|
||||
.getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
||||
return null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseArguments(VersionNumber nowVersion, String[] args) {
|
||||
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
||||
if (!ArrayUtils.contains(args, "--noupdate"))
|
||||
try {
|
||||
if (f.exists()) {
|
||||
Map<String, String> m = C.GSON.fromJson(FileUtils.read(f), Map.class);
|
||||
String s = m.get("ver");
|
||||
if (s != null && VersionNumber.check(s).compareTo(nowVersion) > 0) {
|
||||
String j = m.get("loc");
|
||||
if (j != null) {
|
||||
File jar = new File(j);
|
||||
if (jar.exists() && launchNewerVersion(args, jar))
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JsonSyntaxException ex) {
|
||||
f.delete();
|
||||
} catch (IOException | PrivilegedActionException t) {
|
||||
HMCLog.err("Failed to execute newer version application", t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SimpleEvent<VersionNumber> event) {
|
||||
final VersionNumber version = event.getValue();
|
||||
((UpdateChecker) event.getSource()).requestDownloadLink().reg(map -> {
|
||||
if (MessageBox.show(C.i18n("update.newest_version") + version.firstVer + "." + version.secondVer + "." + version.thirdVer + "\n"
|
||||
+ C.i18n("update.should_open_link"),
|
||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
if (map != null && map.containsKey("jar") && !StrUtils.isBlank(map.get("jar")))
|
||||
try {
|
||||
String hash = null;
|
||||
if (map.containsKey("jarsha1"))
|
||||
hash = map.get("jarsha1");
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderJarTask(map.get("jar"), version.version, hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderJarTask.getSelf(version.version).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Main.LOGGER.log(Level.SEVERE, "Failed to create upgrader", ex);
|
||||
}
|
||||
else if (map != null && map.containsKey("pack") && !StrUtils.isBlank(map.get("pack")))
|
||||
try {
|
||||
String hash = null;
|
||||
if (map.containsKey("packsha1"))
|
||||
hash = map.get("packsha1");
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(map.get("pack"), version.version, hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.version).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to create upgrader", ex);
|
||||
}
|
||||
else {
|
||||
String url = C.URL_PUBLISH;
|
||||
if (map != null)
|
||||
if (map.containsKey(OS.os().checked_name))
|
||||
url = map.get(OS.os().checked_name);
|
||||
else if (map.containsKey(OS.UNKOWN.checked_name))
|
||||
url = map.get(OS.UNKOWN.checked_name);
|
||||
if (url == null)
|
||||
url = C.URL_PUBLISH;
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().browse(new URI(url));
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
HMCLog.err("Failed to browse uri: " + url, e);
|
||||
Utils.setClipborad(url);
|
||||
MessageBox.show(C.i18n("update.no_browser"));
|
||||
}
|
||||
}
|
||||
}).execute();
|
||||
}
|
||||
|
||||
public static class AppDataUpgraderPackGzTask extends Task {
|
||||
|
||||
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
||||
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
|
||||
|
||||
public static File getSelf(String ver) {
|
||||
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
|
||||
}
|
||||
|
||||
private final String downloadLink, newestVersion, expectedHash;
|
||||
File tempFile;
|
||||
|
||||
public AppDataUpgraderPackGzTask(String downloadLink, String newestVersion, String hash) throws IOException {
|
||||
this.downloadLink = downloadLink;
|
||||
this.newestVersion = newestVersion;
|
||||
this.expectedHash = hash;
|
||||
tempFile = File.createTempFile("hmcl", ".pack.gz");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask(boolean areDependTasksSucceeded) throws Exception {
|
||||
if (!areDependTasksSucceeded) {
|
||||
tempFile.delete();
|
||||
return;
|
||||
}
|
||||
HashMap<String, String> json = new HashMap<>();
|
||||
File f = getSelf(newestVersion);
|
||||
if (!FileUtils.makeDirectory(f.getParentFile()))
|
||||
throw new IOException("Failed to make directories: " + f.getParent());
|
||||
|
||||
for (int i = 0; f.exists(); i++)
|
||||
f = new File(BASE_FOLDER, "HMCL-" + newestVersion + (i > 0 ? "-" + i : "") + ".jar");
|
||||
if (!f.createNewFile())
|
||||
throw new IOException("Failed to create new file: " + f);
|
||||
|
||||
try (JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
||||
Pack200.newUnpacker().unpack(new GZIPInputStream(FileUtils.openInputStream(tempFile)), jos);
|
||||
}
|
||||
json.put("ver", newestVersion);
|
||||
json.put("loc", f.getAbsolutePath());
|
||||
String result = C.GSON.toJson(json);
|
||||
FileUtils.write(HMCL_VER_FILE, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Upgrade";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AppDataUpgraderJarTask extends Task {
|
||||
|
||||
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
||||
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
|
||||
|
||||
public static File getSelf(String ver) {
|
||||
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
|
||||
}
|
||||
|
||||
private final String downloadLink, newestVersion, expectedHash;
|
||||
File tempFile;
|
||||
|
||||
public AppDataUpgraderJarTask(String downloadLink, String newestVersion, String hash) throws IOException {
|
||||
this.downloadLink = downloadLink;
|
||||
this.newestVersion = newestVersion;
|
||||
this.expectedHash = hash;
|
||||
tempFile = File.createTempFile("hmcl", ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask(boolean areDependTasksSucceeded) throws Exception {
|
||||
if (!areDependTasksSucceeded) {
|
||||
tempFile.delete();
|
||||
return;
|
||||
}
|
||||
HashMap<String, String> json = new HashMap<>();
|
||||
File f = getSelf(newestVersion);
|
||||
FileUtils.copyFile(tempFile, f);
|
||||
json.put("ver", newestVersion);
|
||||
json.put("loc", f.getAbsolutePath());
|
||||
String result = C.GSON.toJson(json);
|
||||
FileUtils.write(HMCL_VER_FILE, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Upgrade";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.upgrade;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IUpgrader implements Consumer<SimpleEvent<VersionNumber>> {
|
||||
|
||||
public static final IUpgrader NOW_UPGRADER = new AppDataUpgrader();
|
||||
|
||||
/**
|
||||
* Paring arguments to decide on whether the upgrade is needed.
|
||||
*
|
||||
* @param nowVersion now launcher version
|
||||
* @param args Application CommandLine Arguments
|
||||
*/
|
||||
public abstract void parseArguments(VersionNumber nowVersion, String[] args);
|
||||
|
||||
/**
|
||||
* Just download the new app.
|
||||
*
|
||||
* @param sender Should be VersionChecker
|
||||
* @param number the newest version
|
||||
*
|
||||
* @return should return true
|
||||
*/
|
||||
@Override
|
||||
public abstract void accept(SimpleEvent<VersionNumber> event);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.upgrade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
import org.jackhuang.hmcl.util.net.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.util.ArrayUtils;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class NewFileUpgrader extends IUpgrader {
|
||||
|
||||
@Override
|
||||
public void parseArguments(VersionNumber nowVersion, String[] args) {
|
||||
int i = ArrayUtils.indexOf(args, "--removeOldLauncher");
|
||||
if (i != -1 && i < args.length - 1) {
|
||||
File f = new File(args[i + 1]);
|
||||
if (f.exists())
|
||||
f.deleteOnExit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SimpleEvent<VersionNumber> event) {
|
||||
String str = requestDownloadLink();
|
||||
File newf = new File(FileUtils.getName(str));
|
||||
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) {
|
||||
try {
|
||||
new ProcessBuilder(new String[] { newf.getCanonicalPath(), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to start new app", ex);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
private String requestDownloadLink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 382 B |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="SysOut" target="SYSTEM_OUT">
|
||||
<LegacyXMLLayout />
|
||||
<XMLLayout />
|
||||
</Console>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
||||
</Policies>
|
||||
</RollingRandomAccessFile>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||
</filters>
|
||||
<AppenderRef ref="SysOut"/>
|
||||
<AppenderRef ref="File"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 232 B |
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id "me.tatarka.retrolambda" version "3.5.0"
|
||||
//id "org.jetbrains.kotlin.jvm" version "1.1.2-2"
|
||||
}
|
||||
|
||||
if (System.getenv("BUILD_NUMBER") != null)
|
||||
version = System.getenv("BUILD_NUMBER")
|
||||
|
||||
retrolambda {
|
||||
javaVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.EventBus;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class HMCLApi {
|
||||
|
||||
/**
|
||||
* Events.
|
||||
*/
|
||||
public static final EventBus EVENT_BUS = new EventBus();
|
||||
|
||||
public static VersionNumber HMCL_VERSION;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
import org.jackhuang.hmcl.api.ILogger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HMCLog {
|
||||
|
||||
public static ILogger LOGGER;
|
||||
|
||||
public static void log(String message) {
|
||||
LOGGER.log(message);
|
||||
}
|
||||
|
||||
public static void warn(String message) {
|
||||
LOGGER.warn(message);
|
||||
}
|
||||
|
||||
public static void warn(String msg, Throwable t) {
|
||||
LOGGER.warn(msg, t);
|
||||
}
|
||||
|
||||
public static void err(String msg) {
|
||||
LOGGER.err(msg);
|
||||
}
|
||||
|
||||
public static void err(String msg, Throwable t) {
|
||||
LOGGER.err(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface ILogger {
|
||||
|
||||
void log(String message);
|
||||
|
||||
void warn(String message);
|
||||
|
||||
void warn(String msg, Throwable t);
|
||||
|
||||
void err(String msg);
|
||||
|
||||
void err(String msg, Throwable t);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
import org.jackhuang.hmcl.api.ui.AddTabCallback;
|
||||
import javax.swing.JFrame;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
|
||||
/**
|
||||
* Each plugin must implement this interface.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface IPlugin {
|
||||
|
||||
/**
|
||||
* Register authenticators by calling IAuthenticator.LOGINS.add.
|
||||
*
|
||||
* @param apply call apply.accept(your authenticator)
|
||||
*/
|
||||
void onRegisterAuthenticators(Consumer<IAuthenticator> apply);
|
||||
|
||||
/**
|
||||
* Call callback.addTab to add your customized panel to MainFrame RootPane.
|
||||
*
|
||||
* @param frame MainFrame
|
||||
* @param callback call this if you want.
|
||||
*/
|
||||
void onAddTab(JFrame frame, AddTabCallback callback);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public interface IProcess {
|
||||
|
||||
int getExitCode();
|
||||
|
||||
Process getRawProcess();
|
||||
|
||||
String getStartupCommand();
|
||||
|
||||
List<String> getStartupCommands();
|
||||
|
||||
List<String> getStdOutLines();
|
||||
|
||||
boolean isRunning();
|
||||
|
||||
void stop();
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import org.jackhuang.hmcl.api.ui.AddTabCallback;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import javax.swing.JFrame;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
|
||||
/**
|
||||
* Can be only called by HMCL.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class PluginManager {
|
||||
|
||||
private static final File PLUGINS_FILE = new File("plugins").getAbsoluteFile();
|
||||
private static final ArrayList<IPlugin> PLUGINS = new ArrayList<>();
|
||||
|
||||
public static void getPlugin(Class<?> cls) {
|
||||
try {
|
||||
IPlugin p = (IPlugin) cls.newInstance();
|
||||
PLUGINS.add(p);
|
||||
} catch (Throwable e) {
|
||||
System.err.println("Failed to new instance");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void fireRegisterAuthenticators(Consumer<IAuthenticator> callback) {
|
||||
for (IPlugin p : PLUGINS)
|
||||
p.onRegisterAuthenticators(callback);
|
||||
}
|
||||
|
||||
public static void fireAddTab(JFrame frame, AddTabCallback callback) {
|
||||
for (IPlugin p : PLUGINS)
|
||||
p.onAddTab(frame, callback);
|
||||
}
|
||||
|
||||
public static void loadPlugins() {
|
||||
ArrayList<URL> urls = new ArrayList<>();
|
||||
ArrayList<JarFile> jars = new ArrayList<>();
|
||||
if (PLUGINS_FILE.isDirectory()) {
|
||||
for (File f : PLUGINS_FILE.listFiles(f -> f.isFile() && f.getName().endsWith(".jar")))
|
||||
try {
|
||||
jars.add(new JarFile(f));
|
||||
urls.add(f.toURI().toURL());
|
||||
} catch (IOException e) {
|
||||
System.err.println("A malformed jar file: " + f);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
|
||||
for (JarFile f : jars)
|
||||
for (Enumeration<JarEntry> entries = f.entries(); entries.hasMoreElements();)
|
||||
try {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String clsName = entry.getName();
|
||||
if (clsName.endsWith(".class") && !clsName.contains("$")) {
|
||||
clsName = clsName.replace('/', '.').replace(".class", "");
|
||||
Class clazz = classLoader.loadClass(clsName);
|
||||
if (IPlugin.class.isAssignableFrom(clazz))
|
||||
getPlugin(clazz);
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
|
||||
public final byte firstVer, secondVer, thirdVer;
|
||||
public final String version;
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c) {
|
||||
this(a, b, c, null);
|
||||
}
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c, String version) {
|
||||
firstVer = a;
|
||||
secondVer = b;
|
||||
thirdVer = c;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + firstVer + '.' + secondVer + '.' + thirdVer;
|
||||
}
|
||||
|
||||
public static VersionNumber check(String data) {
|
||||
while (!data.isEmpty() && ((data.charAt(0) < '0' || data.charAt(0) > '9') && data.charAt(0) != '.'))
|
||||
data = data.substring(1);
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
VersionNumber ur;
|
||||
String[] ver = data.split("\\.");
|
||||
if (ver.length >= 3) {
|
||||
byte v1, v2, v3;
|
||||
try {
|
||||
v1 = Byte.parseByte(ver[0]);
|
||||
v2 = Byte.parseByte(ver[1]);
|
||||
v3 = Byte.parseByte(ver[2]);
|
||||
ur = new VersionNumber(v1, v2, v3, data);
|
||||
return ur;
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to parse the version", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isOlder(VersionNumber a, VersionNumber b) {
|
||||
if (a.firstVer < b.firstVer)
|
||||
return true;
|
||||
else if (a.firstVer == b.firstVer)
|
||||
if (a.secondVer < b.secondVer)
|
||||
return true;
|
||||
else if (a.secondVer == b.secondVer)
|
||||
if (a.thirdVer < b.thirdVer)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 83 * hash + this.firstVer;
|
||||
hash = 83 * hash + this.secondVer;
|
||||
hash = 83 * hash + this.thirdVer;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final VersionNumber other = (VersionNumber) obj;
|
||||
if (this.firstVer != other.firstVer)
|
||||
return false;
|
||||
if (this.secondVer != other.secondVer)
|
||||
return false;
|
||||
if (this.thirdVer != other.thirdVer)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VersionNumber o) {
|
||||
if (isOlder(this, o))
|
||||
return -1;
|
||||
else if (isOlder(o, this))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class Wrapper<T> {
|
||||
T value;
|
||||
|
||||
public Wrapper(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.auth;
|
||||
|
||||
/**
|
||||
* Thrown if we are trying to log in but there's some problems like password wrong.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AuthenticationException extends Exception {
|
||||
|
||||
public AuthenticationException() {
|
||||
}
|
||||
|
||||
public AuthenticationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AuthenticationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AuthenticationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.auth;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public interface IAuthenticator {
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the name of login method.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
String getPassword();
|
||||
|
||||
String getUserName();
|
||||
|
||||
/**
|
||||
* Has password?
|
||||
*
|
||||
* @return has password?
|
||||
*/
|
||||
boolean hasPassword();
|
||||
|
||||
String id();
|
||||
|
||||
boolean isLoggedIn();
|
||||
|
||||
void logOut();
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
* @param info username & password
|
||||
*
|
||||
* @return login result
|
||||
*
|
||||
* @throws
|
||||
* org.jackhuang.hmcl.core.auth.AuthenticationException
|
||||
*/
|
||||
UserProfileProvider login(LoginInfo info) throws AuthenticationException;
|
||||
|
||||
UserProfileProvider loginBySettings() throws AuthenticationException;
|
||||
|
||||
void onLoadSettings(Map<?, ?> m);
|
||||
|
||||
Map<?, ?> onSaveSettings();
|
||||
|
||||
void setPassword(String password);
|
||||
|
||||
void setRememberMe(boolean is);
|
||||
|
||||
void setUserName(String s);
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.auth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class LoginInfo {
|
||||
|
||||
public String username, password;
|
||||
|
||||
public LoginInfo(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.auth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class UserProfileProvider {
|
||||
|
||||
public String getUserName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public UserProfileProvider setUserName(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public UserProfileProvider setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public UserProfileProvider setSession(String session) {
|
||||
this.session = session;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public UserProfileProvider setAccessToken(String accessToken) {
|
||||
if (accessToken == null)
|
||||
accessToken = "0";
|
||||
this.accessToken = accessToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public UserProfileProvider setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserPropertyMap() {
|
||||
return userPropertyMap;
|
||||
}
|
||||
|
||||
public UserProfileProvider setUserPropertyMap(String userPropertyMap) {
|
||||
this.userPropertyMap = userPropertyMap;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getOtherInfo() {
|
||||
return otherInfo;
|
||||
}
|
||||
|
||||
public UserProfileProvider setOtherInfo(String otherInfo) {
|
||||
this.otherInfo = otherInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getClientIdentifier() {
|
||||
return clientIdentifier;
|
||||
}
|
||||
|
||||
public UserProfileProvider setClientIdentifier(String clientIdentifier) {
|
||||
this.clientIdentifier = clientIdentifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
public UserProfileProvider setUserType(String userType) {
|
||||
this.userType = userType;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String username = "";
|
||||
private String userId = "";
|
||||
private String session = "";
|
||||
private String accessToken = "";
|
||||
private String userProperties = "{}";
|
||||
private String userPropertyMap = "{}";
|
||||
private String otherInfo = "";
|
||||
private String clientIdentifier = "";
|
||||
private String userType = "Offline";
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class EventBus {
|
||||
|
||||
HashMap<Class, EventHandler> events = new HashMap<>();
|
||||
|
||||
public EventBus() {
|
||||
}
|
||||
|
||||
public <T extends EventObject> EventHandler<T> channel(Class<T> classOfT) {
|
||||
if (!events.containsKey(classOfT))
|
||||
events.put(classOfT, new EventHandler<>());
|
||||
return events.get(classOfT);
|
||||
}
|
||||
|
||||
public void fireChannel(EventObject obj) {
|
||||
channel((Class<EventObject>) obj.getClass()).fire(obj);
|
||||
}
|
||||
|
||||
public boolean fireChannelResulted(ResultedEvent obj) {
|
||||
return channel((Class<ResultedEvent>) obj.getClass()).fireResulted(obj);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventObject;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
* @param <T> EventArgs
|
||||
*/
|
||||
public class EventHandler<T extends EventObject> {
|
||||
|
||||
ArrayList<Object> events = new ArrayList<>();
|
||||
|
||||
public EventHandler() {
|
||||
}
|
||||
|
||||
public void register(Consumer<T> t) {
|
||||
if (!events.contains(t))
|
||||
events.add(t);
|
||||
}
|
||||
|
||||
public void registerFirst(Consumer<T> t) {
|
||||
if (!events.contains(t))
|
||||
events.add(0, t);
|
||||
}
|
||||
|
||||
public void register(Runnable t) {
|
||||
if (!events.contains(t))
|
||||
events.add(t);
|
||||
}
|
||||
|
||||
public void registerFirst(Runnable t) {
|
||||
if (!events.contains(t))
|
||||
events.add(0, t);
|
||||
}
|
||||
|
||||
public void fire(T x) {
|
||||
for (Object t : events)
|
||||
if (t instanceof Consumer) {
|
||||
((Consumer) t).accept(x);
|
||||
} else if (t instanceof Runnable)
|
||||
((Runnable) t).run();
|
||||
}
|
||||
|
||||
public boolean fireResulted(T x) {
|
||||
if (!(x instanceof ResultedEvent))
|
||||
throw new IllegalArgumentException("x should be ResultedEvent");
|
||||
ResultedEvent event = (ResultedEvent) x;
|
||||
boolean flag = true;
|
||||
for (Object t : events)
|
||||
if (t instanceof Consumer) {
|
||||
((Consumer) t).accept(x);
|
||||
if (!event.result())
|
||||
flag = false;
|
||||
} else if (t instanceof Runnable)
|
||||
((Runnable) t).run();
|
||||
return flag;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
|
||||
/**
|
||||
* This event gets fired when we found that user's HMCL is out of date.
|
||||
* <br>
|
||||
* This event is {@link org.jackhuang.hmcl.api.ResultedEvent}
|
||||
* If this event is failed, HMCL will not ask user to upgrade the application.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.util.UpdateChecker}
|
||||
* @param VersionNumber newest version
|
||||
* @author huang
|
||||
*/
|
||||
public class OutOfDateEvent extends ResultedSimpleEvent<VersionNumber> {
|
||||
|
||||
public OutOfDateEvent(Object source, VersionNumber value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class PropertyChangedEvent<T> extends EventObject {
|
||||
|
||||
String propertyName;
|
||||
T oldValue, newValue;
|
||||
|
||||
public PropertyChangedEvent(Object source, String propertyName, T oldValue, T newValue) {
|
||||
super(source);
|
||||
this.propertyName = propertyName;
|
||||
this.oldValue = oldValue;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public T getNewValue() {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
public T getOldValue() {
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class ResultedEvent extends EventObject {
|
||||
protected boolean result = true;
|
||||
|
||||
public ResultedEvent(Object sender) {
|
||||
super(sender);
|
||||
}
|
||||
|
||||
public boolean result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void failed() {
|
||||
setResult(false);
|
||||
}
|
||||
|
||||
public void setResult(boolean canceled) {
|
||||
this.result = canceled;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class ResultedSimpleEvent<T> extends ResultedEvent {
|
||||
|
||||
T value;
|
||||
|
||||
public ResultedSimpleEvent(Object sender, T t) {
|
||||
super(sender);
|
||||
value = t;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class SimpleEvent<T> extends EventObject {
|
||||
private T value;
|
||||
|
||||
public SimpleEvent(Object source, T value) {
|
||||
super(source);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.config;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
|
||||
/**
|
||||
* This event gets fired when the authenticator changed.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Config}
|
||||
* @param IAuthenticator the new authenticator.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AuthenticatorChangedEvent extends SimpleEvent<IAuthenticator> {
|
||||
|
||||
public AuthenticatorChangedEvent(Object source, IAuthenticator value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.config;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when the download type changed.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Config}
|
||||
* @param String the new downlaod type name
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DownloadTypeChangedEvent extends SimpleEvent<String> {
|
||||
|
||||
public DownloadTypeChangedEvent(Object source, String value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.config;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.ui.Theme;
|
||||
|
||||
/**
|
||||
* This event gets fired when the application theme changed.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Config}
|
||||
* @param Theme the changed theme
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ThemeChangedEvent extends SimpleEvent<Theme> {
|
||||
|
||||
public ThemeChangedEvent(Object source, Theme value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when we launched the game.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.launch.GameLauncher}
|
||||
* @param IProcess the game process
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchEvent extends SimpleEvent<IProcess> {
|
||||
|
||||
public LaunchEvent(Object source, IProcess value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
import java.util.List;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when we make the launching command successfully(not launched the game process).
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.launch.GameLauncher}
|
||||
* @param List<String> Our launching command.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchSucceededEvent extends SimpleEvent<List<String>>{
|
||||
|
||||
public LaunchSucceededEvent(Object source, List<String> value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum LaunchingState {
|
||||
Starting,
|
||||
LoggingIn,
|
||||
GeneratingLaunchingCodes,
|
||||
DownloadingLibraries,
|
||||
DecompressingNatives,
|
||||
WaitingForGameLaunching,
|
||||
Done
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when we are launching a game and mark what things we are doing.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.launch.GameLauncher}
|
||||
* @param LaunchingState the launching state.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchingStateChangedEvent extends SimpleEvent<LaunchingState> {
|
||||
|
||||
public LaunchingStateChangedEvent(Object source, LaunchingState value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
import org.jackhuang.hmcl.api.Wrapper;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.game.LaunchOptions;
|
||||
|
||||
/**
|
||||
* This event gets fired before generating launch command.
|
||||
* <br>
|
||||
* Pay attension: If you need to terminate the launching process, you must throw
|
||||
* {@link org.jackhuang.hmcl.core.RuntimeGameException anyway.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.launch.GameLauncher}
|
||||
* @param LaunchOptions you can modify the value of this event to control the launching process.
|
||||
* @author huang
|
||||
*/
|
||||
public class ProcessingLaunchOptionsEvent extends SimpleEvent<Wrapper<LaunchOptions>> {
|
||||
|
||||
public ProcessingLaunchOptionsEvent(Object source, Wrapper<LaunchOptions> value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.launch;
|
||||
|
||||
import org.jackhuang.hmcl.api.Wrapper;
|
||||
import org.jackhuang.hmcl.api.auth.UserProfileProvider;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when we successfully logged in.
|
||||
* <br>
|
||||
* Pay attension: If you need to terminate the launching process, you must throw
|
||||
* {@link org.jackhuang.hmcl.core.RuntimeGameException anyway.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.launch.GameLauncher}
|
||||
* @param UserProfileProvider you can modify the value of this event to control the user profile.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ProcessingLoginResultEvent extends SimpleEvent<Wrapper<UserProfileProvider>> {
|
||||
|
||||
public ProcessingLoginResultEvent(Object source, Wrapper<UserProfileProvider> value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.process;
|
||||
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when we launch the JVM and it got crashed.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.util.sys.JavaProcessMonitor}
|
||||
* @param JavaProcess the crashed process.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class JVMLaunchFailedEvent extends SimpleEvent<IProcess> {
|
||||
|
||||
public JVMLaunchFailedEvent(Object source, IProcess value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.process;
|
||||
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when a JavaProcess exited abnormally and the exit code is not zero.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.util.sys.JavaProcessMonitor}
|
||||
* @param JavaProcess The process that exited abnormally.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class JavaProcessExitedAbnormallyEvent extends SimpleEvent<IProcess> {
|
||||
|
||||
public JavaProcessExitedAbnormallyEvent(Object source, IProcess value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.process;
|
||||
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when a JavaProcess is starting.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.util.sys.JavaProcessMonitor}
|
||||
* @param JavaProcess the starting JavaProcess.
|
||||
* @author huang
|
||||
*/
|
||||
public class JavaProcessStartingEvent extends SimpleEvent<IProcess> {
|
||||
|
||||
public JavaProcessStartingEvent(Object source, IProcess value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.process;
|
||||
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when minecraft process exited successfully and the exit code is 0.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.util.sys.JavaProcessMonitor}
|
||||
* @param JavaProcess minecraft process
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class JavaProcessStoppedEvent extends SimpleEvent<IProcess> {
|
||||
|
||||
public JavaProcessStoppedEvent(Object source, IProcess value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.version;
|
||||
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
|
||||
/**
|
||||
* This event gets fired when a minecraft version has been loaded.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.version.MinecraftVersionManager}
|
||||
* @param String the version id.
|
||||
* @author huang
|
||||
*/
|
||||
public class LoadedOneVersionEvent extends SimpleEvent<String> {
|
||||
|
||||
public LoadedOneVersionEvent(Object source, String value) {
|
||||
super(source, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.version;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* This event gets fired when all the versions in .minecraft folder are loaded.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.version.MinecraftVersionManager}
|
||||
* @param IMinecraftService the .minecraft folder.
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class RefreshedVersionsEvent extends EventObject {
|
||||
|
||||
public RefreshedVersionsEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.event.version;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* This event gets fired when loading versions in a .minecraft folder.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.api.HMCLApi#EVENT_BUS}
|
||||
* @param source {@link org.jackhuang.hmcl.core.version.MinecraftVersionManager}
|
||||
* @param IMinecraftService .minecraft folder.
|
||||
* @author huang
|
||||
*/
|
||||
public class RefreshingVersionsEvent extends EventObject {
|
||||
|
||||
public RefreshingVersionsEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.api.func;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface BiFunction<A, B, C> {
|
||||
|
||||
C apply(A a, B b);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user