Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
112a3b1a86 | ||
|
|
f3dc605491 |
No files matched your search
@@ -1,17 +0,0 @@
|
||||
*.class
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
.gradle
|
||||
.nb-gradle
|
||||
|
||||
*.log
|
||||
.mine*
|
||||
*.json
|
||||
*.hmd
|
||||
|
||||
/HMCL/build/
|
||||
/HMCLaF/build/
|
||||
/HMCLAPI/build/
|
||||
/HMCLCore/build/
|
||||
@@ -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>
|
||||
@@ -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/"
|
||||
@@ -1,197 +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/}.
|
||||
*/
|
||||
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.8"
|
||||
id "me.tatarka.retrolambda" version "3.7.0"
|
||||
id 'edu.sc.seis.launch4j' version '2.4.2'
|
||||
//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 = "60"
|
||||
|
||||
def versionroot = System.getenv("VERSION_ROOT")
|
||||
if (versionroot == null)
|
||||
versionroot = "2.7.10"
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
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
|
||||
|
Before Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -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.net.Proxy;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
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.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 {
|
||||
{
|
||||
if (new File("").getAbsolutePath().contains("!")) {
|
||||
MessageBox.show("HMCL cannot run at such path that contains '!'");
|
||||
return;
|
||||
}
|
||||
|
||||
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.asVersion(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, Arrays.asList(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 (Settings.getInstance().getProxyType() != Proxy.Type.DIRECT && StrUtils.isNotBlank(Settings.getInstance().getProxyHost())) {
|
||||
switch (Settings.getInstance().getProxyType()) {
|
||||
case DIRECT:
|
||||
break;
|
||||
case HTTP:
|
||||
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyPort()))
|
||||
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
||||
HMCLog.log("Initialized HTTP proxy.");
|
||||
break;
|
||||
case SOCKS:
|
||||
System.setProperty("socksProxyHost", Settings.getInstance().getProxyHost());
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyPort()))
|
||||
System.setProperty("socksProxyPort", Settings.getInstance().getProxyPort());
|
||||
HMCLog.log("Initialized Socks v4/v5 proxy.");
|
||||
break;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MainFrame.showMainFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeUpdate() {
|
||||
MainFrame.INSTANCE.invokeUpdate();
|
||||
}
|
||||
|
||||
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,358 +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.net.Proxy;
|
||||
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("proxyType")
|
||||
private int proxyType;
|
||||
@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();
|
||||
proxyType = 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 Proxy.Type getProxyType() {
|
||||
if (proxyType < 0 || proxyType >= 3) {
|
||||
proxyType = 0;
|
||||
Settings.save();
|
||||
}
|
||||
return Proxy.Type.values()[proxyType];
|
||||
}
|
||||
|
||||
public void setProxyType(Proxy.Type proxyType) {
|
||||
this.proxyType = proxyType.ordinal();
|
||||
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,182 +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) {
|
||||
VersionSetting vs = service().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.upgrade.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,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -1,601 +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 min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblModpack" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblRestart" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="tabLauncherSettings" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="tabLauncherSettings" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblModpack" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblRestart" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblModpack">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.modpack" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
||||
<Color id="手型光标"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="lblModpackMouseClicked"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblRestart">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.restart" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JTabbedPane" name="tabLauncherSettings">
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/>
|
||||
</AccessibilityProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new NewTabPane()"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pnlGeneral">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation())"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="General">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.tab.general" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</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">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="btnCheckUpdate" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblDownloadSource" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblCommonPath" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblLang" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblProxy" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="28" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="cboProxyType" pref="156" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblProxyHost" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtProxyHost" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblProxyPort" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtProxyPort" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblProxyUserName" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtProxyUsername" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblProxyPassword" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtProxyPassword" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="cboLang" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="txtCommonPath" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnSetCommonPath" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="cboDownloadSource" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</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="lblCommonPath" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtCommonPath" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="btnSetCommonPath" 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="lblDownloadSource" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboDownloadSource" 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="cboLang" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblLang" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="txtProxyHost" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblProxy" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblProxyHost" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtProxyPort" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblProxyPort" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtProxyUsername" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblProxyUserName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtProxyPassword" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblProxyPassword" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboProxyType" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="69" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnCheckUpdate" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="btnMCBBS" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblProxy">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.proxy" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblProxyHost">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="proxy.host" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtProxyHost">
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtProxyHostFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblProxyPort">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="proxy.port" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtProxyPort">
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtProxyPortFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblProxyUserName">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="proxy.username" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtProxyUsername">
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtProxyUsernameFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblProxyPassword">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="proxy.password" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtProxyPassword">
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtProxyPasswordFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboDownloadSource">
|
||||
<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="cboDownloadSourceItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblDownloadSource">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.download_source" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblCommonPath">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.common_location" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtCommonPath">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.commpath_tooltip" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtCommonPathFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnSetCommonPath">
|
||||
<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.explore" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSetCommonPathActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnCheckUpdate">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.update_launcher" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCheckUpdateActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnMCBBS">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="MCBBS"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboLang">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="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")})" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboLangItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblLang">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.lang" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboProxyType">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="3">
|
||||
<StringItem index="0" value="Direct"/>
|
||||
<StringItem index="1" value="HTTP"/>
|
||||
<StringItem index="2" value="Socks"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboProxyTypeItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pnlUI">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation())"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="UI">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.tab.ui" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</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">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="chkEnableShadow" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkEnableBlur" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkEnableAnimation" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="163" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblBackground" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblFont" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblTheme" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cboTheme" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="txtBackgroundPath" max="32767" attributes="0"/>
|
||||
<Component id="cboFontFamily" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="btnSelBackgroundPath" max="32767" attributes="0"/>
|
||||
<Component id="spinnerFontSize" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblExample" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</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="lblBackground" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtBackgroundPath" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="btnSelBackgroundPath" 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="cboFontFamily" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblFont" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spinnerFontSize" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblExample" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cboTheme" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="lblTheme" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="63" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="chkEnableShadow" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkEnableBlur" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkEnableAnimation" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblTheme">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.theme" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboTheme">
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboThemeItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblBackground">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.background_location" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtBackgroundPath">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.background_tooltip" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtBackgroundPathFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkEnableShadow">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.enable_shadow" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkEnableShadowItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkEnableBlur">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.enable_blur" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkEnableBlurItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkEnableAnimation">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.enable_animation" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkEnableAnimationItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkDecorated">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.decorated" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkDecoratedItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnSelBackgroundPath">
|
||||
<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.explore" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSelBackgroundPathActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboFontFamily">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<SerializedValue value="-84,-19,0,5,115,114,0,32,106,97,118,97,120,46,115,119,105,110,103,46,68,101,102,97,117,108,116,67,111,109,98,111,66,111,120,77,111,100,101,108,92,-10,105,-80,-61,-104,-56,48,2,0,2,76,0,7,111,98,106,101,99,116,115,116,0,18,76,106,97,118,97,47,117,116,105,108,47,86,101,99,116,111,114,59,76,0,14,115,101,108,101,99,116,101,100,79,98,106,101,99,116,116,0,18,76,106,97,118,97,47,108,97,110,103,47,79,98,106,101,99,116,59,120,114,0,29,106,97,118,97,120,46,115,119,105,110,103,46,65,98,115,116,114,97,99,116,76,105,115,116,77,111,100,101,108,87,-79,61,-30,108,45,-87,-39,2,0,1,76,0,12,108,105,115,116,101,110,101,114,76,105,115,116,116,0,37,76,106,97,118,97,120,47,115,119,105,110,103,47,101,118,101,110,116,47,69,118,101,110,116,76,105,115,116,101,110,101,114,76,105,115,116,59,120,112,115,114,0,35,106,97,118,97,120,46,115,119,105,110,103,46,101,118,101,110,116,46,69,118,101,110,116,76,105,115,116,101,110,101,114,76,105,115,116,-79,54,-58,125,-124,-22,-42,68,3,0,0,120,112,116,0,34,106,97,118,97,120,46,115,119,105,110,103,46,101,118,101,110,116,46,76,105,115,116,68,97,116,97,76,105,115,116,101,110,101,114,115,114,0,21,106,97,118,97,120,46,115,119,105,110,103,46,74,67,111,109,98,111,66,111,120,115,-25,-16,-68,-83,109,105,-54,3,0,14,90,0,17,102,105,114,105,110,103,65,99,116,105,111,110,69,118,101,110,116,90,0,10,105,115,69,100,105,116,97,98,108,101,90,0,23,108,105,103,104,116,87,101,105,103,104,116,80,111,112,117,112,69,110,97,98,108,101,100,73,0,15,109,97,120,105,109,117,109,82,111,119,67,111,117,110,116,90,0,13,115,101,108,101,99,116,105,110,103,73,116,101,109,76,0,6,97,99,116,105,111,110,116,0,20,76,106,97,118,97,120,47,115,119,105,110,103,47,65,99,116,105,111,110,59,76,0,13,97,99,116,105,111,110,67,111,109,109,97,110,100,116,0,18,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,76,0,28,97,99,116,105,111,110,80,114,111,112,101,114,116,121,67,104,97,110,103,101,76,105,115,116,101,110,101,114,116,0,35,76,106,97,118,97,47,98,101,97,110,115,47,80,114,111,112,101,114,116,121,67,104,97,110,103,101,76,105,115,116,101,110,101,114,59,76,0,9,100,97,116,97,77,111,100,101,108,116,0,27,76,106,97,118,97,120,47,115,119,105,110,103,47,67,111,109,98,111,66,111,120,77,111,100,101,108,59,76,0,6,101,100,105,116,111,114,116,0,28,76,106,97,118,97,120,47,115,119,105,110,103,47,67,111,109,98,111,66,111,120,69,100,105,116,111,114,59,76,0,19,107,101,121,83,101,108,101,99,116,105,111,110,77,97,110,97,103,101,114,116,0,43,76,106,97,118,97,120,47,115,119,105,110,103,47,74,67,111,109,98,111,66,111,120,36,75,101,121,83,101,108,101,99,116,105,111,110,77,97,110,97,103,101,114,59,76,0,21,112,114,111,116,111,116,121,112,101,68,105,115,112,108,97,121,86,97,108,117,101,113,0,126,0,2,76,0,8,114,101,110,100,101,114,101,114,116,0,30,76,106,97,118,97,120,47,115,119,105,110,103,47,76,105,115,116,67,101,108,108,82,101,110,100,101,114,101,114,59,76,0,20,115,101,108,101,99,116,101,100,73,116,101,109,82,101,109,105,110,100,101,114,113,0,126,0,2,120,114,0,22,106,97,118,97,120,46,115,119,105,110,103,46,74,67,111,109,112,111,110,101,110,116,51,-17,99,38,30,108,-90,-113,3,0,16,70,0,10,97,108,105,103,110,109,101,110,116,88,70,0,10,97,108,105,103,110,109,101,110,116,89,90,0,11,97,117,116,111,115,99,114,111,108,108,115,73,0,5,102,108,97,103,115,90,0,15,105,115,65,108,105,103,110,109,101,110,116,88,83,101,116,90,0,15,105,115,65,108,105,103,110,109,101,110,116,89,83,101,116,90,0,26,118,101,114,105,102,121,73,110,112,117,116,87,104,101,110,70,111,99,117,115,84,97,114,103,101,116,76,0,9,97,99,116,105,111,110,77,97,112,116,0,23,76,106,97,118,97,120,47,115,119,105,110,103,47,65,99,116,105,111,110,77,97,112,59,76,0,16,97,110,99,101,115,116,111,114,73,110,112,117,116,77,97,112,116,0,22,76,106,97,118,97,120,47,115,119,105,110,103,47,73,110,112,117,116,77,97,112,59,76,0,6,98,111,114,100,101,114,116,0,27,76,106,97,118,97,120,47,115,119,105,110,103,47,98,111,114,100,101,114,47,66,111,114,100,101,114,59,76,0,13,102,111,99,117,115,73,110,112,117,116,77,97,112,113,0,126,0,19,76,0,13,105,110,112,117,116,86,101,114,105,102,105,101,114,116,0,27,76,106,97,118,97,120,47,115,119,105,110,103,47,73,110,112,117,116,86,101,114,105,102,105,101,114,59,76,0,12,108,105,115,116,101,110,101,114,76,105,115,116,113,0,126,0,4,76,0,9,112,111,112,117,112,77,101,110,117,116,0,24,76,106,97,118,97,120,47,115,119,105,110,103,47,74,80,111,112,117,112,77,101,110,117,59,76,0,21,118,101,116,111,97,98,108,101,67,104,97,110,103,101,83,117,112,112,111,114,116,116,0,34,76,106,97,118,97,47,98,101,97,110,115,47,86,101,116,111,97,98,108,101,67,104,97,110,103,101,83,117,112,112,111,114,116,59,76,0,14,119,105,110,100,111,119,73,110,112,117,116,77,97,112,116,0,31,76,106,97,118,97,120,47,115,119,105,110,103,47,67,111,109,112,111,110,101,110,116,73,110,112,117,116,77,97,112,59,120,114,0,18,106,97,118,97,46,97,119,116,46,67,111,110,116,97,105,110,101,114,64,7,-128,115,-3,20,12,39,3,0,8,73,0,30,99,111,110,116,97,105,110,101,114,83,101,114,105,97,108,105,122,101,100,68,97,116Line truncated
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboFontFamilyItemStateChanged"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFontComboBox()"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblFont">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.log_font" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerFontSize">
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerFontSizeStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblExample">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="19:10:10 [Client Thread/INFO]: Example"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pnlAbout">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new Page().setAnimationEnabled(Settings.getInstance().isEnableAnimation())"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="About">
|
||||
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.tab.about" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblAbout" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="252" max="32767" 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="lblAbout" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblAbout">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="launcher.about" replaceFormat="C.i18n("{key}")"/>
|
||||
</Property>
|
||||
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
||||
<Color id="默认光标"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,672 +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 java.net.Proxy;
|
||||
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());
|
||||
cboProxyType.setSelectedIndex(Settings.getInstance().getProxyType().ordinal());
|
||||
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();
|
||||
cboProxyType = new javax.swing.JComboBox<>();
|
||||
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
|
||||
|
||||
cboProxyType.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Direct", "HTTP", "Socks" }));
|
||||
cboProxyType.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboProxyTypeItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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, 0, Short.MAX_VALUE))
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblDownloadSource)
|
||||
.addComponent(lblCommonPath)
|
||||
.addComponent(lblLang)
|
||||
.addComponent(lblProxy))
|
||||
.addGap(28, 28, 28)
|
||||
.addGroup(pnlGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlGeneralLayout.createSequentialGroup()
|
||||
.addComponent(cboProxyType, 0, 156, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.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))
|
||||
.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)
|
||||
.addComponent(cboProxyType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.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, 163, 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(252, 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
|
||||
|
||||
private void cboProxyTypeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProxyTypeItemStateChanged
|
||||
Settings.getInstance().setProxyType(Proxy.Type.values()[cboProxyType.getSelectedIndex()]);
|
||||
}//GEN-LAST:event_cboProxyTypeItemStateChanged
|
||||
|
||||
// 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<String> cboProxyType;
|
||||
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,254 +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;
|
||||
Log4jHandler logHandler;
|
||||
|
||||
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 {
|
||||
logHandler = new Log4jHandler(monitor, os, false);
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getAccessToken(), "<access token>");
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getSession(), "<session>");
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getUserId(), "<uuid>");
|
||||
logHandler.addForbiddenToken("Setting user: " + obj.getLoginResult().getUserName(), "<player>");
|
||||
logHandler.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) {
|
||||
String log = t.getLine();
|
||||
if (!t.isError() && logHandler != null) {
|
||||
logHandler.newLogLine(log + C.LINE_SEPARATOR);
|
||||
}
|
||||
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)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
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) {
|
||||
MainFrame.INSTANCE.setVisible(true);
|
||||
} else if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible() && !noExitThisTime) {
|
||||
System.exit(0);
|
||||
} else {
|
||||
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.setClipboard(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,504 +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) {
|
||||
int off = enableShadow ? 16 : 0;
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
int contentWidth = width - off - off;
|
||||
int contentHeight = height - off - off;
|
||||
if (!enableShadow || contentWidth <= 0 || contentHeight <= 0)
|
||||
paintImpl(g);
|
||||
else {
|
||||
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,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 == null || 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,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.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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 Map<String, String> getConfigurations() {
|
||||
Map<String, String> map = super.getConfigurations();
|
||||
map.put("${launcher_version}", Main.LAUNCHER_VERSION);
|
||||
map.put("${launcher_name}", Main.LAUNCHER_NAME);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -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,149 +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.PipedOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
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.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class Log4jHandler extends Thread implements Consumer<JavaProcessStoppedEvent> {
|
||||
|
||||
ProcessMonitor monitor;
|
||||
List<Pair<String, String>> forbiddenTokens = new LinkedList<>();
|
||||
AtomicBoolean interrupted = new AtomicBoolean(false);
|
||||
boolean enabled = true;
|
||||
|
||||
public Log4jHandler(ProcessMonitor monitor, PipedOutputStream outputStream, boolean enabled) {
|
||||
this.monitor = monitor;
|
||||
this.enabled = enabled;
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JavaProcessStoppedEvent t) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Always use this instance method to write to the log,
|
||||
* to make sure only this Thread writes to the PipedOutputStream.
|
||||
*
|
||||
* It will also flush the buffer, directly after write.
|
||||
*
|
||||
* This prevents java.io.IOException: Read end dead
|
||||
* See also https://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/
|
||||
*
|
||||
* @param content The content to be written to the log
|
||||
*/
|
||||
public Future newLogLine(String content) {
|
||||
printlnImpl(content, Level.guessLevel(content));
|
||||
return null;
|
||||
}
|
||||
|
||||
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) {
|
||||
printlnImpl(message, l);
|
||||
}
|
||||
}
|
||||
|
||||
private void printlnImpl(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,279 +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.JsonParseException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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.ui.MessageBox;
|
||||
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.Java;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AppDataUpgrader extends IUpgrader {
|
||||
|
||||
private void launchNewerVersion(List<String> args, File jar) throws IOException, ReflectiveOperationException {
|
||||
try (JarFile jarFile = new JarFile(jar)) {
|
||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
if (mainClass == null)
|
||||
throw new ClassNotFoundException("Main-Class not found in manifest");
|
||||
ArrayList<String> al = new ArrayList<>(args);
|
||||
al.add("--noupdate");
|
||||
ClassLoader pre = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
ClassLoader now = new URLClassLoader(new URL[] { jar.toURI().toURL() }, ClassLoader.getSystemClassLoader().getParent());
|
||||
Thread.currentThread().setContextClassLoader(now);
|
||||
now.loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(pre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseArguments(VersionNumber nowVersion, List<String> args) {
|
||||
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
||||
if (!args.contains("--noupdate"))
|
||||
try {
|
||||
if (f.exists()) {
|
||||
Map<String, String> m = C.GSON.fromJson(FileUtils.read(f), new TypeToken<Map<String, String>>() {
|
||||
}.getType());
|
||||
String s = m.get("ver");
|
||||
if (s != null && VersionNumber.asVersion(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 (JsonParseException ex) {
|
||||
f.delete();
|
||||
} catch (IOException | ReflectiveOperationException t) {
|
||||
HMCLog.err("Unable to execute newer version application", t);
|
||||
AppDataUpgraderPackGzTask.HMCL_VER_FILE.delete(); // delete version json, let HMCL re-download the newer version.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SimpleEvent<VersionNumber> event) {
|
||||
final VersionNumber version = event.getValue();
|
||||
((UpdateChecker) event.getSource()).requestDownloadLink().reg(map -> {
|
||||
boolean flag = false;
|
||||
for (Java java : Java.JAVA)
|
||||
if (java.getName().startsWith("1.8") || java.getName().startsWith("9") || java.getName().startsWith("10")) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
if (!flag) {
|
||||
MessageBox.show("请安装 Java 8");
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().browse(new URI("https://java.com"));
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
Utils.setClipboard("https://java.com");
|
||||
MessageBox.show(C.i18n("update.no_browser"));
|
||||
}
|
||||
}
|
||||
|
||||
if (MessageBox.show(C.i18n("update.newest_version") + version.toString() + "\n"
|
||||
+ C.i18n("update.should_open_link"),
|
||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
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.toString(), hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to create upgrader", ex);
|
||||
}
|
||||
else 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.toString(), hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderJarTask.getSelf(version.toString()).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Main.LOGGER.log(Level.SEVERE, "Failed to create upgrader", ex);
|
||||
}
|
||||
else {
|
||||
String url = C.URL_PUBLISH;
|
||||
if (map != null)
|
||||
if (map.containsKey(OS.os().checkedName))
|
||||
url = map.get(OS.os().checkedName);
|
||||
else if (map.containsKey(OS.UNKNOWN.checkedName))
|
||||
url = map.get(OS.UNKNOWN.checkedName);
|
||||
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.setClipboard(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 Collections.singleton(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 (GZIPInputStream in = new GZIPInputStream(FileUtils.openInputStream(tempFile));
|
||||
JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
||||
Pack200.newUnpacker().unpack(in, 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 Collections.singleton(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,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.upgrade;
|
||||
|
||||
import java.util.List;
|
||||
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, List<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,110 +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.util.upgrade;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.api.event.EventHandler;
|
||||
import org.jackhuang.hmcl.util.net.NetUtils;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.event.OutOfDateEvent;
|
||||
import org.jackhuang.hmcl.util.AbstractSwingWorker;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.IUpdateChecker;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class UpdateChecker implements IUpdateChecker {
|
||||
|
||||
private volatile boolean outOfDate = false;
|
||||
public VersionNumber base;
|
||||
public String versionString;
|
||||
public String type;
|
||||
private Map<String, String> download_link = null;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type) {
|
||||
this.base = base;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
VersionNumber value;
|
||||
|
||||
public boolean isOutOfDate() {
|
||||
return outOfDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSwingWorker<VersionNumber> process(final boolean showMessage) {
|
||||
return new AbstractSwingWorker<VersionNumber>() {
|
||||
@Override
|
||||
protected void work() throws Exception {
|
||||
if (value == null) {
|
||||
versionString = NetUtils.get("http://hmcl.huangyuhui.net/api/update?version=" + Main.LAUNCHER_VERSION);
|
||||
value = VersionNumber.asVersion(versionString);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.show(C.i18n("update.failed"));
|
||||
} else if (base.compareTo(value) < 0)
|
||||
outOfDate = true;
|
||||
if (outOfDate)
|
||||
publish(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionNumber getNewVersion() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized AbstractSwingWorker<Map<String, String>> requestDownloadLink() {
|
||||
return new AbstractSwingWorker<Map<String, String>>() {
|
||||
@Override
|
||||
protected void work() throws Exception {
|
||||
if (download_link == null)
|
||||
try {
|
||||
download_link = C.GSON.<Map<String, String>>fromJson(NetUtils.get("http://hmcl.huangyuhui.net/api/update_link?version=" + Main.LAUNCHER_VERSION), Map.class);
|
||||
} catch (JsonSyntaxException | IOException e) {
|
||||
HMCLog.warn("Failed to get update link.", e);
|
||||
}
|
||||
publish(download_link);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final EventHandler<SimpleEvent<VersionNumber>> upgrade = new EventHandler<>();
|
||||
|
||||
@Override
|
||||
public void checkOutdate() {
|
||||
if (outOfDate)
|
||||
if (HMCLApi.EVENT_BUS.fireChannelResulted(new OutOfDateEvent(this, getNewVersion())))
|
||||
upgrade.fire(new SimpleEvent<>(this, getNewVersion()));
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 382 B |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 232 B |
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.apis.LogUtils;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.DoneListener;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.Login;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.LoginInfo;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.LoginResult;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.PluginHandlerType;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraftlauncher.loaders.MinecraftLoader;
|
||||
import org.jackhuang.hellominecraftlauncher.loaders.MinecraftOldLoader;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.PluginHandler;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.SettingsManager;
|
||||
import org.jackhuang.hellominecraftlauncher.settings.Version;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.OperatingSystems;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Compressor;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class GameLauncher {
|
||||
|
||||
private static String makeCommand(List<String> cmd) {
|
||||
StringBuilder cmdbuf = new StringBuilder(120);
|
||||
for (int i = 0; i < cmd.size(); i++) {
|
||||
if (i > 0) {
|
||||
cmdbuf.append(' ');
|
||||
}
|
||||
String s = cmd.get(i);
|
||||
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
|
||||
if (s.charAt(0) != '"') {
|
||||
cmdbuf.append('"');
|
||||
cmdbuf.append(s);
|
||||
if (s.endsWith("\\")) {
|
||||
cmdbuf.append("\\");
|
||||
}
|
||||
cmdbuf.append('"');
|
||||
} else if (s.endsWith("\"")) {
|
||||
/* The argument has already been quoted. */
|
||||
cmdbuf.append(s);
|
||||
} else {
|
||||
/* Unmatched quote for the argument. */
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else {
|
||||
cmdbuf.append(s);
|
||||
}
|
||||
}
|
||||
String str = cmdbuf.toString();
|
||||
|
||||
return str;
|
||||
}
|
||||
Version get;
|
||||
LoginInfo info;
|
||||
Login login;
|
||||
ArrayList<ArrayList<DoneListener<List, GameLauncher>>> listeners;
|
||||
|
||||
public GameLauncher(Version version, LoginInfo info, int loginType) {
|
||||
this.get = version;
|
||||
this.info = info;
|
||||
listeners = new ArrayList<ArrayList<DoneListener<List, GameLauncher>>>(101);
|
||||
for (int i = 0; i < 101; i++) {
|
||||
listeners.add(new ArrayList<DoneListener<List, GameLauncher>>());
|
||||
}
|
||||
this.login = (Login)PluginHandler.getPluginHandlers(PluginHandlerType.getType("LOGIN")).get(loginType);
|
||||
}
|
||||
|
||||
private void executeEvent(int eventType, List p) {
|
||||
for (DoneListener<List, GameLauncher> dl : listeners.get(eventType)) {
|
||||
dl.onDone(p, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(int eventType, DoneListener<List, GameLauncher> dl) {
|
||||
listeners.get(eventType).add(dl);
|
||||
}
|
||||
|
||||
public void makeLaunchCommand() {
|
||||
ArrayList al = new ArrayList();
|
||||
LoginResult result;
|
||||
if(info != null)
|
||||
result = login.login(info);
|
||||
else
|
||||
result = login.loginBySettings();
|
||||
if (result == null || result.success == false) {
|
||||
String error;
|
||||
if (result == null || result.error == null) {
|
||||
error = C.I18N.getString("登录失败:") + C.I18N.getString("插件错误");
|
||||
} else {
|
||||
error = C.I18N.getString("登录失败:") + result.error;
|
||||
}
|
||||
al.add(error);
|
||||
executeEvent(0, al);
|
||||
return;
|
||||
}
|
||||
|
||||
String name = get.name;
|
||||
final String realpa = Utils.addSeparator(Utils.getGameDir(get, SettingsManager.settings.publicSettings.gameDir));
|
||||
|
||||
if (get.isVer16) {
|
||||
String minecraftJar = realpa
|
||||
+ "versions" + File.separator + name + File.separator + name
|
||||
+ ".jar";
|
||||
String minecraftJarTo = realpa
|
||||
+ "versions" + File.separator + name + File.separator + name
|
||||
+ "-HMCL-MERGE-TEMP.jar";
|
||||
|
||||
|
||||
if (get.minecraftJar != null && !get.minecraftJar.isEmpty()) {
|
||||
String unzipDir = Utils.addSeparator(Utils.currentDir())
|
||||
+ "HMCL-MERGE-TEMP" + File.separator;
|
||||
Compressor.unzip(minecraftJar, unzipDir);
|
||||
for (int i = 0; i < get.minecraftJar.size(); i++) {
|
||||
if (get.minecraftJarIsActive == null || get.minecraftJarIsActive.get(i)) {
|
||||
Compressor.unzip(get.minecraftJar.get(i), unzipDir);
|
||||
}
|
||||
}
|
||||
Compressor.zip(unzipDir, minecraftJarTo);
|
||||
Utils.deleteAll(new File(unzipDir));
|
||||
minecraftJar = minecraftJarTo;
|
||||
}
|
||||
|
||||
MinecraftVersion mv = Utils.getMinecraftVersion(get, SettingsManager.settings.publicSettings.gameDir);
|
||||
if (mv.minimumLauncherVersion > Main.minimumLauncherVersion) {
|
||||
MessageBox.Show("对不起,本启动器现在可能不能启动这个版本的Minecraft,但启动器还是会尝试启动");
|
||||
}
|
||||
|
||||
final MinecraftLoader ml = new MinecraftLoader(mv,
|
||||
SettingsManager.settings.publicSettings, get, result,
|
||||
minecraftJar);
|
||||
|
||||
//Find assets
|
||||
|
||||
//Find, download & unzip libraries
|
||||
MinecraftVersion v = (ml).getVersion();
|
||||
File file = new File(realpa + "versions" + File.separator + name + File.separator + name + "-natives");
|
||||
Utils.deleteAll(file);
|
||||
file.mkdirs();
|
||||
ArrayList<String[]> unzippings = new ArrayList<String[]>();
|
||||
ArrayList<String[]> downloadLibraries = new ArrayList<String[]>();
|
||||
|
||||
for (int i = 0; i < v.libraries.size(); i++) {
|
||||
MinecraftLibrary l = v.libraries.get(i);
|
||||
if (l.allow()) {
|
||||
File ff = new File(realpa + "libraries" + File.separator
|
||||
+ l.formatted);
|
||||
if (!ff.exists()) {
|
||||
new File(ff.getParent()).mkdirs();
|
||||
final String location = l.formatted.replace('\\', '/');
|
||||
String[] lib = new String[3];
|
||||
lib[0] = location;
|
||||
lib[1] = C.URL_LIBRARIES[SettingsManager.settings.downloadtype] + location;
|
||||
lib[2] = ff.getPath();
|
||||
downloadLibraries.add(lib);
|
||||
}
|
||||
}
|
||||
if (l.natives != null && l.allow()) {
|
||||
String[] unzip = new String[2];
|
||||
unzip[0] = realpa + "libraries" + File.separator + l.formatted;
|
||||
unzip[1] = realpa + "versions" + File.separator
|
||||
+ name + File.separator + name + "-natives";
|
||||
unzippings.add(unzip);
|
||||
}
|
||||
}
|
||||
|
||||
executeEvent(2, downloadLibraries);
|
||||
executeEvent(3, unzippings);
|
||||
executeEvent(100, ml.makeLaunchingCommand());
|
||||
} else {
|
||||
String minecraftJar = realpa + "bin" + File.separator + "minecraft.jar";
|
||||
String minecraftJarTo = realpa + "bin" + File.separator + "minecraft-HMCL-MERGE-TEMP.jar";
|
||||
|
||||
if (get.minecraftJar != null && !get.minecraftJar.isEmpty()) {
|
||||
String unzipDir = Utils.addSeparator(Utils.currentDir())
|
||||
+ "HMCL-MERGE-TEMP" + File.separator;
|
||||
Compressor.unzip(minecraftJar, unzipDir);
|
||||
for (int i = 0; i < get.minecraftJar.size(); i++) {
|
||||
if (get.minecraftJarIsActive == null || get.minecraftJarIsActive.get(i)) {
|
||||
Compressor.unzip(get.minecraftJar.get(i), unzipDir);
|
||||
}
|
||||
}
|
||||
Compressor.zip(unzipDir, minecraftJarTo);
|
||||
Utils.deleteAll(new File(unzipDir));
|
||||
minecraftJar = minecraftJarTo;
|
||||
}
|
||||
String command;
|
||||
MinecraftOldLoader loader = new MinecraftOldLoader(
|
||||
SettingsManager.settings.publicSettings, get, result,
|
||||
minecraftJar);
|
||||
command = makeCommand(loader.makeLaunchingCommand());
|
||||
al.add(command);
|
||||
executeEvent(100, al);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the game "as soon as possible".
|
||||
* @param str launch command
|
||||
*/
|
||||
public void launch(List str) {
|
||||
try {
|
||||
Process p;
|
||||
File dir = new File(Utils.getGameDir(get, SettingsManager.settings.publicSettings.gameDir));
|
||||
String appdata = dir.getParent();
|
||||
LogUtils.info("APPDATA: " + appdata);
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
builder.environment().put("APPDATA", appdata);
|
||||
builder.directory(dir);
|
||||
p = builder.start();
|
||||
ArrayList<JavaProcess> al = new ArrayList<JavaProcess>();
|
||||
al.add(new JavaProcess(str, p));
|
||||
executeEvent(4, al);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
MessageBox.Show(C.I18N.getString("启动失败"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* According to the name...
|
||||
*
|
||||
* @param launcherName the name of launch bat/sh
|
||||
* @param str launch command
|
||||
*/
|
||||
public void makeLauncher(String launcherName, List str) {
|
||||
|
||||
OperatingSystems os = Utils.os();
|
||||
String gameDir = Utils.getGameDir(get, SettingsManager.settings.publicSettings.gameDir);
|
||||
File f;
|
||||
boolean isWin = os == OperatingSystems.WINDOWS;
|
||||
if (isWin) {
|
||||
f = new File(launcherName + ".bat");
|
||||
} else {
|
||||
f = new File(launcherName + ".sh");
|
||||
}
|
||||
if (!f.exists()) {
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), System.getProperty("sun.jnu.encoding", "gbk")));
|
||||
} catch (FileNotFoundException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(GameLauncher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
|
||||
} catch (FileNotFoundException ex1) {
|
||||
throw new RuntimeException(ex1);
|
||||
}
|
||||
}
|
||||
if (isWin) {
|
||||
|
||||
File dir = new File(gameDir);
|
||||
String appdata = dir.getParent();
|
||||
if (appdata != null) {
|
||||
try {
|
||||
writer.write("set appdata=" + appdata);
|
||||
writer.newLine();
|
||||
} catch (IOException ex) {
|
||||
System.err.println("Failed to write.");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
writer.write(makeCommand(str));
|
||||
writer.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(GameLauncher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (!isWin) {
|
||||
try {
|
||||
Runtime.getRuntime().exec("chmod +x launch.sh");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public enum GameLauncherRequest {
|
||||
|
||||
ERROR,
|
||||
DOWNLOAD_ASSETS,
|
||||
DOWNLOAD_LIBRARIES,
|
||||
UNZIP_LIBRARIES,
|
||||
PROCESS_STARTED,
|
||||
SUCCEED
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
|
||||
\u6e38\u620f\u7248\u672c=\u6e38\u620f\u7248\u672c
|
||||
\u8fd9\u4e2aMINECRAFT\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0V0\u3002=\u8fd9\u4e2aminecraft\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0v0\u3002
|
||||
\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c=\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c
|
||||
\u5bfc\u5165\u5931\u8d25\:\ {0}=\u5bfc\u5165\u5931\u8d25: {0}
|
||||
\u627e\u5230\u540c\u540d\u7684MINECRAFT\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0=\u627e\u5230\u540c\u540d\u7684Minecraft\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0
|
||||
\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0=\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0
|
||||
\u627e\u4e0d\u5230MINECRAFT.JAR=\u627e\u4e0d\u5230minecraft.jar
|
||||
\u9009\u62e9MINECRAFT\u8def\u5f84=\u9009\u62e9Minecraft\u8def\u5f84
|
||||
\u542f\u52a8\u5931\u8d25=\u542f\u52a8\u5931\u8d25
|
||||
\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25\:\ =\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25:
|
||||
\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25\:\ =\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25:
|
||||
\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25\:\ =\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25:
|
||||
\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}=\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}
|
||||
\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMINECRAFT\u7248\u672c=\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMinecraft\u7248\u672c
|
||||
\u9519\u8bef\u7684MINECRAFT\u8def\u5f84=\u9519\u8bef\u7684Minecraft\u8def\u5f84
|
||||
\u5173\u4e8e=\u5173\u4e8e
|
||||
\u4e0b\u8f7d=\u4e0b\u8f7d
|
||||
\u5bc6\u7801=\u5bc6\u7801
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52a8\u8bbe\u7f6e
|
||||
\u4e0d\u9650\u5236=\u4e0d\u9650\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u542f\u52a8\u6a21\u5f0f
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5185\u5b58
|
||||
\u6e38\u620f\u540d\u79f0=\u540d\u5b57
|
||||
\u6e38\u620f\u8def\u5f84=\u6e38\u620f\u8def\u5f84
|
||||
\u5bfc\u5165\u6587\u4ef6\u5939=\u5bfc\u5165\u6587\u4ef6\u5939
|
||||
\u65b0\u5efa=\u65b0\u5efa
|
||||
\u5220\u9664=\u5220\u9664
|
||||
\u7f16\u8f91=\u7f16\u8f91
|
||||
\u590d\u5236=\u590d\u5236
|
||||
\u5bfc\u5165\u65e7\u7248\u672c=\u5bfc\u5165\u65e7\u7248\u672c
|
||||
\u5236\u4f5c\u4e00\u952e\u542f\u52a8=\u5236\u4f5c\u4e00\u952e\u542f\u52a8
|
||||
\u51c6\u5907\u4e2d=\u51c6\u5907\u4e2d
|
||||
\u5f00\u59cbMINECRAFT\u4e4b\u65c5!=\u542f\u52a8\u6e38\u620f
|
||||
\u5237\u65b0=\u5237\u65b0
|
||||
public_settings=\u5168\u5c40\u8bbe\u7f6e
|
||||
game_download=\u6e38\u620f\u4e0b\u8f7d
|
||||
\u66f4\u65b0\u4fe1\u606f=\u66f4\u65b0\u4fe1\u606f
|
||||
\u8bbe\u7f6e\u5931\u8d25\uff1a=\u8bbe\u7f6e\u5931\u8d25\uff1a
|
||||
\u7f3a\u5931\u5e93\u4e0b\u8f7d=\u7f3a\u5931\u5e93\u4e0b\u8f7d
|
||||
\u9009\u62e9\u80cc\u666f\u8def\u5f84=\u9009\u62e9\u80cc\u666f\u8def\u5f84
|
||||
MineLogin0=\u7f51\u7edc\u9519\u8bef
|
||||
MineLogin1=\u7528\u6237\u540d\u6216\u5bc6\u7801\u4e0d\u5408\u6cd5
|
||||
MineLogin2=\u5185\u90e8\u9519\u8bef
|
||||
MineLogin3=\u7528\u6237\u4e0d\u5b58\u5728
|
||||
MineLogin4=\u9700\u8981\u9a8c\u8bc1
|
||||
MineLogin5=\u5bc6\u7801\u9519\u8bef
|
||||
ForgeMod=Forge mod
|
||||
ModLoaderMod=ModLoader mod
|
||||
Forge=Forge
|
||||
ModLoader=ModLoader
|
||||
Unknown=\u672a\u77e5
|
||||
Mods\u6587\u4ef6\u5939=Mods\u6587\u4ef6\u5939
|
||||
Coremods\u6587\u4ef6\u5939=Coremods\u6587\u4ef6\u5939
|
||||
Mod\u72ec\u7acb\u6587\u4ef6\u5939=Mod\u72ec\u7acb\u6587\u4ef6\u5939
|
||||
\u914d\u7f6e\u6587\u4ef6\u5939=\u914d\u7f6e\u6587\u4ef6\u5939
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u5f55\u5931\u8d25\uff1a
|
||||
\u9009\u62e9\u5931\u8d25=\u9009\u62e9\u5931\u8d25
|
||||
\u63d2\u4ef6\u9519\u8bef\uff1a=\u63d2\u4ef6\u9519\u8bef\uff1a
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u5f55\u5931\u8d25\uff1a
|
||||
\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...=\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...
|
||||
\u4fdd\u5b58=\u4fdd\u5b58
|
||||
\u767b\u5f55\u6a21\u5f0f=\u767b\u5f55\u6a21\u5f0f
|
||||
\u7248\u672c\u7f16\u8f91=\u7248\u672c\u7f16\u8f91
|
||||
\u7248\u672c\u53f7=\u7248\u672c\u53f7
|
||||
\u5bfc\u5165=\u5bfc\u5165
|
||||
\u64cd\u4f5c=\u64cd\u4f5c
|
||||
\u4e0b\u8f7d\u4fe1\u606f=\u4e0b\u8f7d\u4fe1\u606f
|
||||
\u5b89\u88c5=\u5b89\u88c5
|
||||
\u6dfb\u52a0=\u6dfb\u52a0
|
||||
\u5168\u90e8\u4e0b\u8f7d=\u5168\u90e8\u4e0b\u8f7d
|
||||
\u52a0\u5165MINECRAFT.JAR=\u52a0\u5165minecraft.jar
|
||||
\u7ba1\u7406=\u7ba1\u7406
|
||||
\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4=\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4
|
||||
\u5e93=\u5e93
|
||||
AdvancedSettings=\u9ad8\u7ea7\u8bbe\u7f6e
|
||||
\u6700\u5927\u5316=\u6700\u5927\u5316
|
||||
\u68c0\u67e5\u66f4\u65b0=\u68c0\u67e5\u66f4\u65b0
|
||||
\u67e5\u770b\u65e5\u5fd7=\u67e5\u770b\u65e5\u5fd7
|
||||
\u80cc\u666f\u5730\u5740=\u80cc\u666f\u5730\u5740
|
||||
UNEXPECTED\ EXCEPTION\ LOADING\ =Unexpected exception loading
|
||||
\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c=\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c
|
||||
\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762=\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762
|
||||
\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f=\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f
|
||||
\u66f4\u65b0\u4fe1\u606f\u4e3a\:\ =\u66f4\u65b0\u4fe1\u606f\u4e3a:
|
||||
\u6700\u65b0\u7248\u672c\u4e3a\uff1a=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
||||
\u68c0\u67e5\u66f4\u65b0\u5931\u8d25=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
||||
\u8fde\u63a5\u4e2d=\u8fde\u63a5\u4e2d
|
||||
\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5=\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5
|
||||
INVALID\ PLUGIN=Invalid plugin
|
||||
\u65e0\u6cd5\u8fde\u63a5=\u65e0\u6cd5\u8fde\u63a5
|
||||
\ \u5dee\ ORANGERED=\ \u5dee orangered
|
||||
\ \u8f83\u5dee\ ORANGE=\ \u8f83\u5dee orange
|
||||
\ \u4e2d\ YELLOGREEN=\ \u4e2d yellogreen
|
||||
\ \u8f83\u597d\ BLUE=\ \u8f83\u597d blue
|
||||
\ \u597d\ GREEN=\ \u597d green
|
||||
\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548=\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548
|
||||
ForgeInstall=\u63a5\u4e0b\u6765\u5f39\u51fa\u6765\u7684\u7a97\u53e3\u91cc\u8bf7\u9009\u62e9\u8def\u5f84\u4e3a\u6e38\u620f\u8def\u5f84\u3002\u7a0b\u5e8f\u5df2\u7ecf\u5c06\u76ee\u5f55\u590d\u5236\u5230\u4e86\u526a\u8d34\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u91cc\u9009\u62e9"..."\u6309\u94ae\uff0c\u7c98\u8d34\u8def\u5f84\uff0c\u786e\u5b9a\u5373\u53ef
|
||||
\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668\:\ =\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668:
|
||||
\u63d0\u793a=\u63d0\u793a
|
||||
\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0=\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0
|
||||
\u540d\u79f0=\u540d\u79f0
|
||||
\u4fdd\u5b58\u5931\u8d25=\u4fdd\u5b58\u5931\u8d25
|
||||
\u4fdd\u5b58\u538b\u7f29\u5305\u5230=\u4fdd\u5b58\u538b\u7f29\u5305\u5230
|
||||
\u9009\u62e9\u6750\u8d28\u5305=\u9009\u62e9\u6750\u8d28\u5305
|
||||
\u9009\u62e9\u8d44\u6e90\u5305=\u9009\u62e9\u8d44\u6e90\u5305
|
||||
\u9009\u62e9\u5e93/\u6a21\u7ec4=\u9009\u62e9\u5e93/\u6a21\u7ec4
|
||||
\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002=\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002
|
||||
\u5220\u9664\u5931\u8d25=\u5220\u9664\u5931\u8d25
|
||||
\u6dfb\u52a0\u5931\u8d25=\u6dfb\u52a0\u5931\u8d25
|
||||
\u9009\u62e9\u6a21\u7ec4=\u9009\u62e9\u6a21\u7ec4
|
||||
\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a=\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a
|
||||
\u5907\u4efd\u5230=\u5907\u4efd\u5230
|
||||
\u662fCOREODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4=\u662fCoremods\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4
|
||||
\u662fMODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4=\u662fMods\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4
|
||||
\u901a\u5e38\u662f\u6a21\u7ec4=\u901a\u5e38\u662f\u6a21\u7ec4
|
||||
\u4e0b\u79fb=\u4e0b\u79fb
|
||||
\u4e0a\u79fb=\u4e0a\u79fb
|
||||
\u5220\u9664=\u5220\u9664
|
||||
\u589e\u52a0=\u589e\u52a0
|
||||
\u901a\u5e38\u662fFORGE,MODLOADER\u4ee5\u53caMINECRAFT\u6240\u4f9d\u8d56\u7684\u5e93=\u901a\u5e38\u662fForge,Modloader\u4ee5\u53caMinecraft\u6240\u4f9d\u8d56\u7684\u5e93
|
||||
\u9644\u52a0\u542f\u52a8\u53c2\u6570=\u9644\u52a0\u542f\u52a8\u53c2\u6570
|
||||
\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(LIBRARIES\u6587\u4ef6\u5939)=\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(libraries\u6587\u4ef6\u5939)
|
||||
\u4e3b\u7c7b=\u4e3b\u7c7b
|
||||
\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(ASSETS\u6587\u4ef6\u5939)=\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(assets\u6587\u4ef6\u5939)
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52a8\u8bbe\u7f6e
|
||||
\u4e0d\u5f3a\u5236=\u4e0d\u5f3a\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u542f\u52a8\u6a21\u5f0f
|
||||
\u73a9\u5bb6\u540d=\u73a9\u5bb6\u540d
|
||||
1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c=1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5185\u5b58\uff08MB\uff09
|
||||
JAVA\u865a\u62df\u673a\u53c2\u6570=Java\u865a\u62df\u673a\u53c2\u6570
|
||||
JAVA\u8def\u5f84=Java\u8def\u5f84
|
||||
\u5168\u5c4f=\u5168\u5c4f
|
||||
\u5206\u8fa8\u7387=\u5206\u8fa8\u7387
|
||||
\u6e38\u620f\u8def\u5f84=\u6e38\u620f\u8def\u5f84
|
||||
\u4ee5\u4e0b\u8bbe\u7f6e\u5b57\u6bb5\u4e3a\u7a7a\u4ee3\u8868\u7740\u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e=\u9664\u540d\u79f0\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u4e0d\u586b
|
||||
\u53d6\u6d88=\u53d6\u6d88
|
||||
\u786e\u5b9a=\u786e\u5b9a
|
||||
game_download=\u6e38\u620f\u4e0b\u8f7d
|
||||
public_settings=\u5168\u5c40\u8bbe\u7f6e
|
||||
invalid=\u65e0\u6548\u7684
|
||||
invalid_jar=\u65e0\u6548\u7684jar\u5305
|
||||
not_a_file=\u4e0d\u662f\u6587\u4ef6
|
||||
not_found=\u627e\u4e0d\u5230minecraft.jar
|
||||
not_readable=minecraft.jar\u4e0d\u53ef\u8bfb
|
||||
modified=(\u4fee\u6539\u7684!)
|
||||
\u83b7\u53d6\u4e2d=\u83b7\u53d6\u4e2d
|
||||
\u63d2\u4ef6\u9519\u8bef=\u63d2\u4ef6\u9519\u8bef
|
||||
CannotLoadPluginsBecauseOfAnError=\u65e0\u6cd5\u52a0\u8f7d\u63d2\u4ef6\uff0c\u56e0\u4e3a\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef\u3002
|
||||
CRASH\ REPORT\ DETECTED,\ BUT\ UNKNOWN\ FORMAT\:=Crash report detected, but unknown format:
|
||||
COULDN'T\ OPEN\ CRASH\ REPORT=Couldn't open crash report
|
||||
CRASH\ REPORT\ DETECTED,\ OPENING\:=Crash report detected, opening:
|
||||
MinecraftCrashed=Minecraft\u5d29\u6e83\u4e86\uff01(\u9519\u8bef\u4ee3\u7801:{0})
|
||||
RememberMe=\u8bb0\u4f4f\u6211
|
||||
Logout=\u767b\u51fa
|
||||
ShowIfIsLoaded=\u663e\u793a\u63d2\u4ef6\u662f\u5426\u52a0\u8f7d\uff0c\u70b9\u51fb\u67e5\u770b\u9519\u8bef
|
||||
IsLoaded=\u662f\u5426\u52a0\u8f7d
|
||||
PluginSettings=\u63d2\u4ef6\u8bbe\u7f6e
|
||||
Details=\u4fe1\u606f
|
||||
Authors=\u4f5c\u8005
|
||||
Version=\u7248\u672c
|
||||
Name=\u540d\u79f0
|
||||
CheckUpdate=\u68c0\u67e5\u672c\u542f\u52a8\u5668\u7684\u66f4\u65b0
|
||||
DownloadSource=\u4e0b\u8f7d\u6e90
|
||||
DisableMoveMods=\u7981\u6b62\u7248\u672c\u81ea\u6709\u6a21\u7ec4\uff08\u79fb\u52a8\u6a21\u7ec4\uff09\u529f\u80fd
|
||||
ShowConsoleOutput=\u5c31\u662fMinecraft\u7684\u63a7\u5236\u53f0\u8f93\u51fa
|
||||
MinecraftLocation=Minecraft\u8def\u5f84\uff08\u5373.minecraft\u6587\u4ef6\u5939\uff09
|
||||
MaxMemoryTooltip=\u5141\u8bb8Minecraft\u6700\u591a\u5141\u8bb8\u4f7f\u7528\u7684\u5185\u5b58\uff08\u770b\u4e0d\u61c2\u5c31\u4f7f\u7528\u9ed8\u8ba4\u76841024\u5427\uff09
|
||||
FailedToLoad=\u52a0\u8f7d\u5931\u8d25
|
||||
Loaded=\u5df2\u52a0\u8f7d
|
||||
NoCharacter=\u8be5\u5e10\u53f7\u6ca1\u6709\u89d2\u8272
|
||||
LegacyLogin=\u65e7\u7248\u6b63\u7248\u767b\u5f55
|
||||
YggdrasilLogin=\u65b0\u7248\u6b63\u7248\u767b\u5f55
|
||||
PleaseChooseCharacter=\u8bf7\u9009\u62e9\u60a8\u8981\u4f7f\u7528\u7684\u89d2\u8272
|
||||
WrongPassword=\u53ef\u80fd\u662f\u60a8\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
|
||||
OfflineLogin=\u79bb\u7ebf\u6a21\u5f0f
|
||||
GameDownload=\u6e38\u620f\u4e0b\u8f7d
|
||||
IntegrateDownload=\u6574\u5408\u5305\u4e0b\u8f7d
|
||||
AssetsDownload=\u8d44\u6e90\u4e0b\u8f7d
|
||||
Installers=\u81ea\u52a8\u5b89\u88c5
|
||||
WorldSaving=\u5907\u4efd\u5730\u56fe
|
||||
ServerEditor=\u670d\u52a1\u5668\u7f16\u8f91
|
||||
TexturepackEditor=\u6750\u8d28\u5305\u7ba1\u7406
|
||||
Refresh=\u5237\u65b0\u5217\u8868
|
||||
Install=\u5b89\u88c5
|
||||
AssetsType=\u8d44\u6e90\u7c7b\u578b
|
||||
InstallOptifine=\u5b89\u88c5\u9009\u4e2d\u7684Optifine
|
||||
Changelog=\u66f4\u65b0\u4fe1\u606f
|
||||
InstallForge=\u5b89\u88c5\u9009\u4e2d\u7684Forge
|
||||
ModManaging=\u6a21\u7ec4\u7ba1\u7406
|
||||
PluginCenter=\u63d2\u4ef6\u4e2d\u5fc3
|
||||
ExtMods=\u5916\u90e8\u6a21\u7ec4
|
||||
CoreMods=\u6838\u5fc3\u6a21\u7ec4
|
||||
NormalSettings=\u666e\u901a\u8bbe\u7f6e
|
||||
1.6AndAbove=1.6\u53ca\u4ee5\u4e0a
|
||||
1.5AndBelow=1.5\u53ca\u4ee5\u4e0b
|
||||
IsActive=\u6d3b\u52a8
|
||||
Location=\u8def\u5f84
|
||||
Type=\u7c7b\u578b
|
||||
ReleaseTime=\u91ca\u653e\u65f6\u95f4
|
||||
Time=\u53d1\u5e03\u65f6\u95f4
|
||||
Version=\u7248\u672c
|
||||
MCVersion=MC\u7248\u672c
|
||||
IntegrateName=\u6574\u5408\u5305\u540d\u79f0
|
||||
IntegrateVersion=\u6574\u5408\u5305\u7248\u672c
|
||||
ServerName=\u670d\u52a1\u5668\u540d\u79f0
|
||||
HideAddress=\u9690\u85cf\u5730\u5740
|
||||
Address=\u5730\u5740
|
||||
Introduction=\u4ecb\u7ecd
|
||||
Online=\u5728\u7ebf
|
||||
Delay=\u5ef6\u8fdf
|
||||
Clear=\u6e05\u9664
|
||||
Close=\u5173\u95ed
|
||||
Save=\u4fdd\u5b58
|
||||
JoinMinecraftJar=\u52a0\u5165minecraft.jar
|
||||
ExternalMods=\u5916\u90e8\u6a21\u7ec4
|
||||
DynamicLoadingMods=\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4
|
||||
Libraries=\u5e93
|
||||
TagArguments=\u9644\u52a0\u7ed9\u4e88Minecraft\u7684\u53c2\u6570
|
||||
MainClass=Minecraft\u7684\u4e3b\u7c7b\uff08\u4e0d\u77e5\u9053\u4ec0\u4e48\u610f\u601d\u7684\u8bdd\u4e5f\u5c31\u7528\u4e0d\u4e0a\u4e86\uff09
|
||||
DefaultLibrariesFolder=\u9ed8\u8ba4\u4e3a.minecraft/libraries\u6587\u4ef6\u5939
|
||||
DefaultAssetsFolder=\u9ed8\u8ba4\u4e3a.minecraft/assets\u6587\u4ef6\u5939
|
||||
MakeMCMaximum=\u4f7fMinecraft\u7a97\u53e3\u6700\u5927\u5316
|
||||
MCFolderFormat=\u5c31\u662fMinecraft\u6587\u4ef6\u5939\u683c\u5f0f
|
||||
MakeMCFullscreen=\u4f7fMinecraft\u7a97\u53e3\u5168\u5c4f
|
||||
MCHeight=Minecraft\u7a97\u53e3\u9ad8
|
||||
MCWidth=Minecraft\u7a97\u53e3\u5bbd
|
||||
Personalization=\u4e2a\u6027\u5316
|
||||
MaxPermGen=\u6700\u5927\u6c38\u4e45\u4fdd\u5b58\u533a\u57df\uff08MB\uff09
|
||||
Options=\u8bbe\u7f6e
|
||||
Setup=\u8bbe\u7f6e
|
||||
@@ -0,0 +1,230 @@
|
||||
\u6e38\u620f\u7248\u672c=Game versions
|
||||
\u8fd9\u4e2aMINECRAFT\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0V0\u3002=This chosen minecraft folder is not a format of version 1.6 above or 1.5 below, so the launcher cannot import it.
|
||||
\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c=Not version selected.
|
||||
\u5bfc\u5165\u5931\u8d25\:\ {0}=Failed to include: {0}
|
||||
\u627e\u5230\u540c\u540d\u7684MINECRAFT\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0=Already existed a Minecraft version which has same name, please use another name.
|
||||
\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0=Please enter the name of this old version
|
||||
\u627e\u4e0d\u5230MINECRAFT.JAR=Cannot find minecraft.jar
|
||||
\u9009\u62e9MINECRAFT\u8def\u5f84=Choose Minecraft path
|
||||
\u542f\u52a8\u5931\u8d25=Failed to launch
|
||||
\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25\:\ =Failed to copy config folder:
|
||||
\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25\:\ =Failed to copy coremods folder:
|
||||
\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25\:\ =Failed to copy mods foler:
|
||||
\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}=Download missing libraries\uff1a{0}
|
||||
\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMINECRAFT\u7248\u672c=Not version selected.
|
||||
\u9519\u8bef\u7684MINECRAFT\u8def\u5f84=An erroneous Minecraft path.
|
||||
\u5173\u4e8e=About
|
||||
\u4e0b\u8f7d=Download
|
||||
\u5bc6\u7801=Password
|
||||
\u624b\u52a8\u8bbe\u7f6e=Select
|
||||
\u4e0d\u9650\u5236=Default
|
||||
32\u4f4d=32 bit
|
||||
64\u4f4d=64 bit
|
||||
\u542f\u52a8\u6a21\u5f0f=Launch mode
|
||||
\u6700\u5927\u5185\u5b58=Max memory(MB)
|
||||
\u6e38\u620f\u540d\u79f0=User name
|
||||
\u6e38\u620f\u8def\u5f84=Game location
|
||||
\u5bfc\u5165\u6587\u4ef6\u5939=Import folder
|
||||
\u65b0\u5efa=New
|
||||
\u5220\u9664=Delete
|
||||
\u7f16\u8f91=Edit
|
||||
\u590d\u5236=Copy
|
||||
\u5bfc\u5165\u65e7\u7248\u672c=Import old version
|
||||
\u5236\u4f5c\u4e00\u952e\u542f\u52a8=Make bat/sh launcher
|
||||
\u51c6\u5907\u4e2d=Preparing
|
||||
\u5f00\u59cbMINECRAFT\u4e4b\u65c5!=Enjoy Minecraft now!
|
||||
\u5237\u65b0=Refresh
|
||||
game_download=Game downloads
|
||||
public_settings=Public settings
|
||||
\u8bbe\u7f6e\u5931\u8d25\uff1a=Failed to set\uff1a
|
||||
\u7f3a\u5931\u5e93\u4e0b\u8f7d=Download missing libraries
|
||||
\u9009\u62e9\u80cc\u666f\u8def\u5f84=Choose background image path
|
||||
MineLogin0=Network error
|
||||
MineLogin1=User name or password is incorrect
|
||||
MineLogin2=Internal error
|
||||
MineLogin3=User does not exist
|
||||
MineLogin4=Need to verify
|
||||
MineLogin5=Wrong password
|
||||
ForgeMod=Forge mod
|
||||
ModLoaderMod=ModLoader mod
|
||||
Forge=Forge
|
||||
ModLoader=ModLoader
|
||||
Unknown=Unknown
|
||||
Mods\u6587\u4ef6\u5939=Mods folder
|
||||
Coremods\u6587\u4ef6\u5939=Coremods folder
|
||||
Mod\u72ec\u7acb\u6587\u4ef6\u5939=Moddir folder
|
||||
\u914d\u7f6e\u6587\u4ef6\u5939=Config folder
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=Failed to login
|
||||
\u9009\u62e9\u5931\u8d25=Failed to select
|
||||
\u63d2\u4ef6\u9519\u8bef\uff1a=Plugin error\uff1a
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=Failed to login\uff1a
|
||||
\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...=No sign...
|
||||
\u4fdd\u5b58=Save
|
||||
\u767b\u5f55\u6a21\u5f0f=Log-In mode
|
||||
\u7248\u672c\u7f16\u8f91=Preferences
|
||||
\u7248\u672c\u53f7=Version
|
||||
\u5bfc\u5165=Import
|
||||
\u64cd\u4f5c=Operations
|
||||
\u4e0b\u8f7d\u4fe1\u606f=Download Info
|
||||
\u5b89\u88c5=Install
|
||||
\u6dfb\u52a0=Add
|
||||
\u5168\u90e8\u4e0b\u8f7d=Download all
|
||||
\u52a0\u5165MINECRAFT.JAR=Join minecraft.jar
|
||||
\u7ba1\u7406=Managings
|
||||
\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4=Dynamic Loading Mods
|
||||
\u5e93=Libraries
|
||||
AdvancedSettings=Advanced
|
||||
\u6700\u5927\u5316=Maximized
|
||||
\u68c0\u67e5\u66f4\u65b0=Check for updates
|
||||
\u67e5\u770b\u65e5\u5fd7=View Log
|
||||
\u80cc\u666f\u5730\u5740=Background Location
|
||||
UNEXPECTED\ EXCEPTION\ LOADING\ =Unexpected exception loading
|
||||
\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c=This is the latest version
|
||||
\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762=Unable to open the browser, the URL has been copied to the clipboard, you can paste the URL manually open the page
|
||||
\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f=Do you wish to go to the publishing page to update?
|
||||
\u66f4\u65b0\u4fe1\u606f\u4e3a\:\ =Update notes:
|
||||
\u6700\u65b0\u7248\u672c\u4e3a\uff1a=Latest version\uff1a
|
||||
\u68c0\u67e5\u66f4\u65b0\u5931\u8d25=Failed to check update
|
||||
\u8fde\u63a5\u4e2d=Connecting
|
||||
\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5=Failed to get the list, please retry to refresh
|
||||
INVALID\ PLUGIN=Invalid plugin
|
||||
\u65e0\u6cd5\u8fde\u63a5=Unable to connect
|
||||
\ \u5dee\ ORANGERED=\ Bad orangered
|
||||
\ \u8f83\u5dee\ ORANGE=\ Not good orange
|
||||
\ \u4e2d\ YELLOGREEN=\ So-so yellogreen
|
||||
\ \u8f83\u597d\ BLUE=\ OK blue
|
||||
\ \u597d\ GREEN=\ Good green
|
||||
\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548=The reply of the server {0} is invalid
|
||||
\u63a5\u4e0b\u6765\u5f39\u51fa\u6765\u7684\u7a97\u53e3\u91cc\u8bf7\u9009\u62e9\u8def\u5f84\u4e3a\u6e38\u620f\u8def\u5f84\u3002\u7a0b\u5e8f\u5df2\u7ecf\u5c06\u76ee\u5f55\u590d\u5236\u5230\u4e86\u526a\u8d34\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u91cc\u9009\u62e9\\"...\\"\u6309\u94ae\uff0c\u7c98\u8d34\u8def\u5f84\uff0c\u786e\u5b9a\u5373\u53ef=In the next pop-up window, select the path as the game paths. Launcher has been copied the directory to the clipboard. In the window, choose \\"...\\" button, paste the path, and click OK. It can be determined.
|
||||
\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668\:\ =Can not open Explorer:
|
||||
\u63d0\u793a=Notice
|
||||
\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0=Enter the name of the new version
|
||||
\u540d\u79f0=Name
|
||||
\u4fdd\u5b58\u5931\u8d25=Failed to save
|
||||
\u4fdd\u5b58\u538b\u7f29\u5305\u5230=Save zip file to
|
||||
\u9009\u62e9\u6750\u8d28\u5305=Choose texture pack
|
||||
\u9009\u62e9\u8d44\u6e90\u5305=Choose resource pack
|
||||
\u9009\u62e9\u5e93/\u6a21\u7ec4=Choose library/mod
|
||||
\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002=Not selected any library/mod.
|
||||
\u5220\u9664\u5931\u8d25=Failed to delete
|
||||
\u6dfb\u52a0\u5931\u8d25=Failed to add
|
||||
\u9009\u62e9\u6a21\u7ec4=Choose mod
|
||||
\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a=Version name cannot be empty.
|
||||
\u5907\u4efd\u5230=Backup to
|
||||
\u662fCOREODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4=They're all the core mods in coremods folder.
|
||||
\u662fMODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4=They're all the mods in mods folder.
|
||||
\u901a\u5e38\u662f\u6a21\u7ec4=Usually mods.
|
||||
\u4e0b\u79fb=Down
|
||||
\u4e0a\u79fb=Up
|
||||
\u5220\u9664=Delete
|
||||
\u589e\u52a0=Add
|
||||
\u901a\u5e38\u662fFORGE,MODLOADER\u4ee5\u53caMINECRAFT\u6240\u4f9d\u8d56\u7684\u5e93=They're usually Forge, Modloader and libraries.
|
||||
\u9644\u52a0\u542f\u52a8\u53c2\u6570=Addition arguments
|
||||
\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(LIBRARIES\u6587\u4ef6\u5939)=Customize libraries folder
|
||||
\u4e3b\u7c7b=Main class
|
||||
\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(ASSETS\u6587\u4ef6\u5939)=Customize assets folder
|
||||
\u624b\u52a8\u8bbe\u7f6e=Manually set
|
||||
\u4e0d\u5f3a\u5236=Default
|
||||
32\u4f4d=32 bit
|
||||
64\u4f4d=64 bit
|
||||
\u542f\u52a8\u6a21\u5f0f=Launch mode
|
||||
\u73a9\u5bb6\u540d=Player name
|
||||
1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c=Version 1.6 and above, and imported the old version
|
||||
\u6700\u5927\u5185\u5b58=Max memory
|
||||
JAVA\u865a\u62df\u673a\u53c2\u6570=JVM arguments
|
||||
JAVA\u8def\u5f84=Java path
|
||||
\u5168\u5c4f=Fullscreen
|
||||
\u5206\u8fa8\u7387=Resolution
|
||||
\u6e38\u620f\u8def\u5f84=Game dir
|
||||
\u4ee5\u4e0b\u8bbe\u7f6e\u5b57\u6bb5\u4e3a\u7a7a\u4ee3\u8868\u7740\u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e=These field could not fill except the name field.
|
||||
\u53d6\u6d88=Cancel
|
||||
\u786e\u5b9a=Ok
|
||||
invalid=invalid
|
||||
invalid_jar=invalid jar
|
||||
not_a_file=not a file
|
||||
not_found=not found
|
||||
not_readable=not readable
|
||||
modified=(modified!)
|
||||
\u83b7\u53d6\u4e2d=Loading
|
||||
\u63d2\u4ef6\u9519\u8bef=Plugin error
|
||||
CannotLoadPluginsBecauseOfAnError=Cannot load plugins because an error occurred.
|
||||
CRASH\ REPORT\ DETECTED,\ BUT\ UNKNOWN\ FORMAT\:=Crash report detected, but unknown format:
|
||||
COULDN'T\ OPEN\ CRASH\ REPORT=Couldn't open crash report
|
||||
CRASH\ REPORT\ DETECTED,\ OPENING\:=Crash report detected, opening:
|
||||
MinecraftCrashed=Minecraft crashed! (Error code: {0})
|
||||
RememberMe=Remember me
|
||||
Logout=Log out
|
||||
ShowIfIsLoaded=To show if plugins are loaded.
|
||||
IsLoaded=Is loaded
|
||||
PluginSettings=Plugin settings
|
||||
Details=Details
|
||||
Authors=Authors
|
||||
Version=Version
|
||||
Name=Name
|
||||
CheckUpdate=Check for update
|
||||
DownloadSource=Download source
|
||||
DisableMoveMods=Disable moving mods.
|
||||
ShowConsoleOutput=To show Minecraft console output.
|
||||
MinecraftLocation=Minecraft location
|
||||
MaxMemoryTooltip=Maximum memory(default 1024)
|
||||
FailedToLoad=Failed to load
|
||||
Loaded=Loaded
|
||||
NoCharacter=No characters
|
||||
LegacyLogin=Legacy
|
||||
YggdrasilLogin=Yggdrasil
|
||||
PleaseChooseCharacter=Please choose the character you want to use.
|
||||
WrongPassword=Maybe your user name or password is wrong.
|
||||
OfflineLogin=Offline
|
||||
GameDownload=Downloads
|
||||
IntegrateDownload=Integrate Packs
|
||||
AssetsDownload=Assets
|
||||
Installers=Installers
|
||||
WorldSaving=World Backups
|
||||
ServerEditor=Server List
|
||||
TexturepackEditor=Texturepacks
|
||||
Refresh=Refresh
|
||||
AssetsType=Type
|
||||
Install=Install
|
||||
InstallOptifine=Install selected Optifine
|
||||
Changelog=Changelog
|
||||
InstallForge=Install selected Forge
|
||||
ModManaging=Mods
|
||||
PluginCenter=Plugins
|
||||
ExtMods=External Mods
|
||||
CoreMods=Core Mods
|
||||
NormalSettings=Normal
|
||||
1.6AndAbove=1.6 And Above
|
||||
1.5AndBelow=1.5 And Below
|
||||
IsActive=Active
|
||||
Location=Location
|
||||
Type=Type
|
||||
ReleaseTime=Release Time
|
||||
Time=Time
|
||||
Version=Version
|
||||
MCVersion=MC Version
|
||||
IntegrateName=Pack Name
|
||||
IntegrateVersion=Pack Version
|
||||
ServerName=Server Name
|
||||
HideAddress=Hide Address
|
||||
Address=Address
|
||||
Introduction=Introduction
|
||||
Online=Online
|
||||
Delay=Delay
|
||||
Clear=Clear
|
||||
Close=Close
|
||||
Save=Save
|
||||
JoinMinecraftJar=Join minecraft.jar
|
||||
ExternalMods=External Mods
|
||||
DynamicLoadingMods=Dynamic Loading Mods
|
||||
Libraries=Libraries
|
||||
TagArguments=Tag Args
|
||||
MainClass=Minecraft Main Class
|
||||
DefaultLibrariesFolder=Default: .minecraft/libraries
|
||||
DefaultAssetsFolder=Default: .minecraft/assets
|
||||
MakeMCMaximum=Make Minecraft Maximum
|
||||
MCFolderFormat=Minecraft Folder format
|
||||
MakeMCFullscreen=Make Minecraft fullscreen
|
||||
MCHeight=Minecraft window height
|
||||
MCWidth=Minecraft window width
|
||||
Personalization=Personalization
|
||||
MaxPermGen=Max PermGen Size(MB)
|
||||
@@ -0,0 +1,236 @@
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
|
||||
\u6e38\u620f\u7248\u672c=\u6e38\u620f\u7248\u672c
|
||||
\u8fd9\u4e2aMINECRAFT\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0V0\u3002=\u8fd9\u4e2aminecraft\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0v0\u3002
|
||||
\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c=\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c
|
||||
\u5bfc\u5165\u5931\u8d25\:\ {0}=\u5bfc\u5165\u5931\u8d25: {0}
|
||||
\u627e\u5230\u540c\u540d\u7684MINECRAFT\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0=\u627e\u5230\u540c\u540d\u7684Minecraft\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0
|
||||
\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0=\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0
|
||||
\u627e\u4e0d\u5230MINECRAFT.JAR=\u627e\u4e0d\u5230minecraft.jar
|
||||
\u9009\u62e9MINECRAFT\u8def\u5f84=\u9009\u62e9Minecraft\u8def\u5f84
|
||||
\u542f\u52a8\u5931\u8d25=\u542f\u52a8\u5931\u8d25
|
||||
\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25\:\ =\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25:
|
||||
\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25\:\ =\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25:
|
||||
\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25\:\ =\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25:
|
||||
\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}=\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}
|
||||
\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMINECRAFT\u7248\u672c=\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMinecraft\u7248\u672c
|
||||
\u9519\u8bef\u7684MINECRAFT\u8def\u5f84=\u9519\u8bef\u7684Minecraft\u8def\u5f84
|
||||
\u5173\u4e8e=\u5173\u4e8e
|
||||
\u4e0b\u8f7d=\u4e0b\u8f7d
|
||||
\u5bc6\u7801=\u5bc6\u7801
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52a8\u8bbe\u7f6e
|
||||
\u4e0d\u9650\u5236=\u4e0d\u9650\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u542f\u52a8\u6a21\u5f0f
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5185\u5b58
|
||||
\u6e38\u620f\u540d\u79f0=\u540d\u5b57
|
||||
\u6e38\u620f\u8def\u5f84=\u6e38\u620f\u8def\u5f84
|
||||
\u5bfc\u5165\u6587\u4ef6\u5939=\u5bfc\u5165\u6587\u4ef6\u5939
|
||||
\u65b0\u5efa=\u65b0\u5efa
|
||||
\u5220\u9664=\u5220\u9664
|
||||
\u7f16\u8f91=\u7f16\u8f91
|
||||
\u590d\u5236=\u590d\u5236
|
||||
\u5bfc\u5165\u65e7\u7248\u672c=\u5bfc\u5165\u65e7\u7248\u672c
|
||||
\u5236\u4f5c\u4e00\u952e\u542f\u52a8=\u5236\u4f5c\u4e00\u952e\u542f\u52a8
|
||||
\u51c6\u5907\u4e2d=\u51c6\u5907\u4e2d
|
||||
\u5f00\u59cbMINECRAFT\u4e4b\u65c5!=\u5f00\u59cbMinecraft\u4e4b\u65c5!
|
||||
\u5237\u65b0=\u5237\u65b0
|
||||
public_settings=\u5168\u5c40\u8bbe\u7f6e
|
||||
game_download=\u6e38\u620f\u4e0b\u8f7d
|
||||
\u8bbe\u7f6e\u5931\u8d25\uff1a=\u8bbe\u7f6e\u5931\u8d25\uff1a
|
||||
\u7f3a\u5931\u5e93\u4e0b\u8f7d=\u7f3a\u5931\u5e93\u4e0b\u8f7d
|
||||
\u9009\u62e9\u80cc\u666f\u8def\u5f84=\u9009\u62e9\u80cc\u666f\u8def\u5f84
|
||||
MineLogin0=\u7f51\u7edc\u9519\u8bef
|
||||
MineLogin1=\u7528\u6237\u540d\u6216\u5bc6\u7801\u4e0d\u5408\u6cd5
|
||||
MineLogin2=\u5185\u90e8\u9519\u8bef
|
||||
MineLogin3=\u7528\u6237\u4e0d\u5b58\u5728
|
||||
MineLogin4=\u9700\u8981\u9a8c\u8bc1
|
||||
MineLogin5=\u5bc6\u7801\u9519\u8bef
|
||||
ForgeMod=Forge mod
|
||||
ModLoaderMod=ModLoader mod
|
||||
Forge=Forge
|
||||
ModLoader=ModLoader
|
||||
Unknown=\u672a\u77e5
|
||||
Mods\u6587\u4ef6\u5939=Mods\u6587\u4ef6\u5939
|
||||
Coremods\u6587\u4ef6\u5939=Coremods\u6587\u4ef6\u5939
|
||||
Mod\u72ec\u7acb\u6587\u4ef6\u5939=Mod\u72ec\u7acb\u6587\u4ef6\u5939
|
||||
\u914d\u7f6e\u6587\u4ef6\u5939=\u914d\u7f6e\u6587\u4ef6\u5939
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u5f55\u5931\u8d25\uff1a
|
||||
\u9009\u62e9\u5931\u8d25=\u9009\u62e9\u5931\u8d25
|
||||
\u63d2\u4ef6\u9519\u8bef\uff1a=\u63d2\u4ef6\u9519\u8bef\uff1a
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u5f55\u5931\u8d25\uff1a
|
||||
\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...=\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...
|
||||
\u4fdd\u5b58=\u4fdd\u5b58
|
||||
\u767b\u5f55\u6a21\u5f0f=\u767b\u5f55\u6a21\u5f0f
|
||||
\u7248\u672c\u7f16\u8f91=\u7248\u672c\u7f16\u8f91
|
||||
\u7248\u672c\u53f7=\u7248\u672c\u53f7
|
||||
\u5bfc\u5165=\u5bfc\u5165
|
||||
\u64cd\u4f5c=\u64cd\u4f5c
|
||||
\u4e0b\u8f7d\u4fe1\u606f=\u4e0b\u8f7d\u4fe1\u606f
|
||||
\u5b89\u88c5=\u5b89\u88c5
|
||||
\u6dfb\u52a0=\u6dfb\u52a0
|
||||
\u5168\u90e8\u4e0b\u8f7d=\u5168\u90e8\u4e0b\u8f7d
|
||||
\u52a0\u5165MINECRAFT.JAR=\u52a0\u5165minecraft.jar
|
||||
\u7ba1\u7406=\u7ba1\u7406
|
||||
\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4=\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4
|
||||
\u5e93=\u5e93
|
||||
AdvancedSettings=\u9ad8\u7ea7\u8bbe\u7f6e
|
||||
\u6700\u5927\u5316=\u6700\u5927\u5316
|
||||
\u68c0\u67e5\u66f4\u65b0=\u68c0\u67e5\u66f4\u65b0
|
||||
\u67e5\u770b\u65e5\u5fd7=\u67e5\u770b\u65e5\u5fd7
|
||||
\u80cc\u666f\u5730\u5740=\u80cc\u666f\u5730\u5740
|
||||
UNEXPECTED\ EXCEPTION\ LOADING\ =Unexpected exception loading
|
||||
\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c=\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c
|
||||
\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762=\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762
|
||||
\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f=\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f
|
||||
\u66f4\u65b0\u4fe1\u606f\u4e3a\:\ =\u66f4\u65b0\u4fe1\u606f\u4e3a:
|
||||
\u6700\u65b0\u7248\u672c\u4e3a\uff1a=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
||||
\u68c0\u67e5\u66f4\u65b0\u5931\u8d25=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
||||
\u8fde\u63a5\u4e2d=\u8fde\u63a5\u4e2d
|
||||
\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5=\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5
|
||||
INVALID\ PLUGIN=Invalid plugin
|
||||
\u65e0\u6cd5\u8fde\u63a5=\u65e0\u6cd5\u8fde\u63a5
|
||||
\ \u5dee\ ORANGERED=\ \u5dee orangered
|
||||
\ \u8f83\u5dee\ ORANGE=\ \u8f83\u5dee orange
|
||||
\ \u4e2d\ YELLOGREEN=\ \u4e2d yellogreen
|
||||
\ \u8f83\u597d\ BLUE=\ \u8f83\u597d blue
|
||||
\ \u597d\ GREEN=\ \u597d green
|
||||
\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548=\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548
|
||||
\u63a5\u4e0b\u6765\u5f39\u51fa\u6765\u7684\u7a97\u53e3\u91cc\u8bf7\u9009\u62e9\u8def\u5f84\u4e3a\u6e38\u620f\u8def\u5f84\u3002\u7a0b\u5e8f\u5df2\u7ecf\u5c06\u76ee\u5f55\u590d\u5236\u5230\u4e86\u526a\u8d34\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u91cc\u9009\u62e9\\"...\\"\u6309\u94ae\uff0c\u7c98\u8d34\u8def\u5f84\uff0c\u786e\u5b9a\u5373\u53ef=\u63a5\u4e0b\u6765\u5f39\u51fa\u6765\u7684\u7a97\u53e3\u91cc\u8bf7\u9009\u62e9\u8def\u5f84\u4e3a\u6e38\u620f\u8def\u5f84\u3002\u7a0b\u5e8f\u5df2\u7ecf\u5c06\u76ee\u5f55\u590d\u5236\u5230\u4e86\u526a\u8d34\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u91cc\u9009\u62e9\\"...\\"\u6309\u94ae\uff0c\u7c98\u8d34\u8def\u5f84\uff0c\u786e\u5b9a\u5373\u53ef
|
||||
\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668\:\ =\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668:
|
||||
\u63d0\u793a=\u63d0\u793a
|
||||
\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0=\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0
|
||||
\u540d\u79f0=\u540d\u79f0
|
||||
\u4fdd\u5b58\u5931\u8d25=\u4fdd\u5b58\u5931\u8d25
|
||||
\u4fdd\u5b58\u538b\u7f29\u5305\u5230=\u4fdd\u5b58\u538b\u7f29\u5305\u5230
|
||||
\u9009\u62e9\u6750\u8d28\u5305=\u9009\u62e9\u6750\u8d28\u5305
|
||||
\u9009\u62e9\u8d44\u6e90\u5305=\u9009\u62e9\u8d44\u6e90\u5305
|
||||
\u9009\u62e9\u5e93/\u6a21\u7ec4=\u9009\u62e9\u5e93/\u6a21\u7ec4
|
||||
\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002=\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002
|
||||
\u5220\u9664\u5931\u8d25=\u5220\u9664\u5931\u8d25
|
||||
\u6dfb\u52a0\u5931\u8d25=\u6dfb\u52a0\u5931\u8d25
|
||||
\u9009\u62e9\u6a21\u7ec4=\u9009\u62e9\u6a21\u7ec4
|
||||
\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a=\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a
|
||||
\u5907\u4efd\u5230=\u5907\u4efd\u5230
|
||||
\u662fCOREODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4=\u662fCoremods\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4
|
||||
\u662fMODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4=\u662fMods\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4
|
||||
\u901a\u5e38\u662f\u6a21\u7ec4=\u901a\u5e38\u662f\u6a21\u7ec4
|
||||
\u4e0b\u79fb=\u4e0b\u79fb
|
||||
\u4e0a\u79fb=\u4e0a\u79fb
|
||||
\u5220\u9664=\u5220\u9664
|
||||
\u589e\u52a0=\u589e\u52a0
|
||||
\u901a\u5e38\u662fFORGE,MODLOADER\u4ee5\u53caMINECRAFT\u6240\u4f9d\u8d56\u7684\u5e93=\u901a\u5e38\u662fForge,Modloader\u4ee5\u53caMinecraft\u6240\u4f9d\u8d56\u7684\u5e93
|
||||
\u9644\u52a0\u542f\u52a8\u53c2\u6570=\u9644\u52a0\u542f\u52a8\u53c2\u6570
|
||||
\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(LIBRARIES\u6587\u4ef6\u5939)=\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(libraries\u6587\u4ef6\u5939)
|
||||
\u4e3b\u7c7b=\u4e3b\u7c7b
|
||||
\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(ASSETS\u6587\u4ef6\u5939)=\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(assets\u6587\u4ef6\u5939)
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52a8\u8bbe\u7f6e
|
||||
\u4e0d\u5f3a\u5236=\u4e0d\u5f3a\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u542f\u52a8\u6a21\u5f0f
|
||||
\u73a9\u5bb6\u540d=\u73a9\u5bb6\u540d
|
||||
1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c=1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5185\u5b58
|
||||
JAVA\u865a\u62df\u673a\u53c2\u6570=Java\u865a\u62df\u673a\u53c2\u6570
|
||||
JAVA\u8def\u5f84=Java\u8def\u5f84
|
||||
\u5168\u5c4f=\u5168\u5c4f
|
||||
\u5206\u8fa8\u7387=\u5206\u8fa8\u7387
|
||||
\u6e38\u620f\u8def\u5f84=\u6e38\u620f\u8def\u5f84
|
||||
\u4ee5\u4e0b\u8bbe\u7f6e\u5b57\u6bb5\u4e3a\u7a7a\u4ee3\u8868\u7740\u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e=\u9664\u540d\u79f0\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u4e0d\u586b
|
||||
\u53d6\u6d88=\u53d6\u6d88
|
||||
\u786e\u5b9a=\u786e\u5b9a
|
||||
game_download=\u6e38\u620f\u4e0b\u8f7d
|
||||
public_settings=\u5168\u5c40\u8bbe\u7f6e
|
||||
invalid=\u65e0\u6548\u7684
|
||||
invalid_jar=\u65e0\u6548\u7684jar\u5305
|
||||
not_a_file=\u4e0d\u662f\u6587\u4ef6
|
||||
not_found=\u627e\u4e0d\u5230minecraft.jar
|
||||
not_readable=minecraft.jar\u4e0d\u53ef\u8bfb
|
||||
modified=(\u4fee\u6539\u7684!)
|
||||
\u83b7\u53d6\u4e2d=\u83b7\u53d6\u4e2d
|
||||
\u63d2\u4ef6\u9519\u8bef=\u63d2\u4ef6\u9519\u8bef
|
||||
CannotLoadPluginsBecauseOfAnError=\u65e0\u6cd5\u52a0\u8f7d\u63d2\u4ef6\uff0c\u56e0\u4e3a\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef\u3002
|
||||
CRASH\ REPORT\ DETECTED,\ BUT\ UNKNOWN\ FORMAT\:=Crash report detected, but unknown format:
|
||||
COULDN'T\ OPEN\ CRASH\ REPORT=Couldn't open crash report
|
||||
CRASH\ REPORT\ DETECTED,\ OPENING\:=Crash report detected, opening:
|
||||
MinecraftCrashed=Minecraft\u5d29\u6e83\u4e86\uff01(\u9519\u8bef\u4ee3\u7801:{0})
|
||||
RememberMe=\u8bb0\u4f4f\u6211
|
||||
Logout=\u767b\u51fa
|
||||
ShowIfIsLoaded=\u663e\u793a\u63d2\u4ef6\u662f\u5426\u52a0\u8f7d\uff0c\u70b9\u51fb\u67e5\u770b\u9519\u8bef
|
||||
IsLoaded=\u662f\u5426\u52a0\u8f7d
|
||||
PluginSettings=\u63d2\u4ef6\u8bbe\u7f6e
|
||||
Details=\u4fe1\u606f
|
||||
Authors=\u4f5c\u8005
|
||||
Version=\u7248\u672c
|
||||
Name=\u540d\u79f0
|
||||
CheckUpdate=\u68c0\u67e5\u672c\u542f\u52a8\u5668\u7684\u66f4\u65b0
|
||||
DownloadSource=\u4e0b\u8f7d\u6e90
|
||||
DisableMoveMods=\u7981\u6b62\u7248\u672c\u81ea\u6709\u6a21\u7ec4\uff08\u79fb\u52a8\u6a21\u7ec4\uff09\u529f\u80fd
|
||||
ShowConsoleOutput=\u5c31\u662fMinecraft\u7684\u63a7\u5236\u53f0\u8f93\u51fa
|
||||
MinecraftLocation=Minecraft\u8def\u5f84\uff08\u5373.minecraft\u6587\u4ef6\u5939\uff09
|
||||
MaxMemoryTooltip=\u5141\u8bb8Minecraft\u6700\u591a\u5141\u8bb8\u4f7f\u7528\u7684\u5185\u5b58\uff08\u770b\u4e0d\u61c2\u5c31\u4f7f\u7528\u9ed8\u8ba4\u76841024\u5427\uff09
|
||||
FailedToLoad=\u52a0\u8f7d\u5931\u8d25
|
||||
Loaded=\u5df2\u52a0\u8f7d
|
||||
|
||||
NoCharacter=\u8be5\u5e10\u53f7\u6ca1\u6709\u89d2\u8272
|
||||
LegacyLogin=\u65e7\u7248\u6b63\u7248\u767b\u5f55
|
||||
YggdrasilLogin=\u65b0\u7248\u6b63\u7248\u767b\u5f55
|
||||
PleaseChooseCharacter=\u8bf7\u9009\u62e9\u60a8\u8981\u4f7f\u7528\u7684\u89d2\u8272
|
||||
WrongPassword=\u53ef\u80fd\u662f\u60a8\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
|
||||
OfflineLogin=\u79bb\u7ebf\u6a21\u5f0f
|
||||
GameDownload=\u6e38\u620f\u4e0b\u8f7d
|
||||
IntegrateDownload=\u6574\u5408\u5305\u4e0b\u8f7d
|
||||
AssetsDownload=\u8d44\u6e90\u4e0b\u8f7d
|
||||
Installers=\u81ea\u52a8\u5b89\u88c5
|
||||
WorldSaving=\u5907\u4efd\u5730\u56fe
|
||||
ServerEditor=\u670d\u52a1\u5668\u7f16\u8f91
|
||||
TexturepackEditor=\u6750\u8d28\u5305\u7ba1\u7406
|
||||
Refresh=\u5237\u65b0\u5217\u8868
|
||||
Install=\u5b89\u88c5
|
||||
AssetsType=\u8d44\u6e90\u7c7b\u578b
|
||||
InstallOptifine=\u5b89\u88c5\u9009\u4e2d\u7684Optifine
|
||||
Changelog=\u66f4\u65b0\u4fe1\u606f
|
||||
InstallForge=\u5b89\u88c5\u9009\u4e2d\u7684Forge
|
||||
ModManaging=\u6a21\u7ec4\u7ba1\u7406
|
||||
PluginCenter=\u63d2\u4ef6\u4e2d\u5fc3
|
||||
ExtMods=\u5916\u90e8\u6a21\u7ec4
|
||||
CoreMods=\u6838\u5fc3\u6a21\u7ec4
|
||||
NormalSettings=\u666e\u901a\u8bbe\u7f6e
|
||||
1.6AndAbove=1.6\u53ca\u4ee5\u4e0a
|
||||
1.5AndBelow=1.5\u53ca\u4ee5\u4e0b
|
||||
IsActive=\u6d3b\u52a8
|
||||
Location=\u8def\u5f84
|
||||
Type=\u7c7b\u578b
|
||||
ReleaseTime=\u91ca\u653e\u65f6\u95f4
|
||||
Time=\u53d1\u5e03\u65f6\u95f4
|
||||
Version=\u7248\u672c
|
||||
MCVersion=MC\u7248\u672c
|
||||
IntegrateName=\u6574\u5408\u5305\u540d\u79f0
|
||||
IntegrateVersion=\u6574\u5408\u5305\u7248\u672c
|
||||
ServerName=\u670d\u52a1\u5668\u540d\u79f0
|
||||
HideAddress=\u9690\u85cf\u5730\u5740
|
||||
Address=\u5730\u5740
|
||||
Introduction=\u4ecb\u7ecd
|
||||
Online=\u5728\u7ebf
|
||||
Delay=\u5ef6\u8fdf
|
||||
Clear=\u6e05\u9664
|
||||
Close=\u5173\u95ed
|
||||
Save=\u4fdd\u5b58
|
||||
JoinMinecraftJar=\u52a0\u5165minecraft.jar
|
||||
ExternalMods=\u5916\u90e8\u6a21\u7ec4
|
||||
DynamicLoadingMods=\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4
|
||||
Libraries=\u5e93
|
||||
TagArguments=\u9644\u52a0\u7ed9\u4e88Minecraft\u7684\u53c2\u6570
|
||||
MainClass=Minecraft\u7684\u4e3b\u7c7b\uff08\u4e0d\u77e5\u9053\u4ec0\u4e48\u610f\u601d\u7684\u8bdd\u4e5f\u5c31\u7528\u4e0d\u4e0a\u4e86\uff09
|
||||
DefaultLibrariesFolder=\u9ed8\u8ba4\u4e3a.minecraft/libraries\u6587\u4ef6\u5939
|
||||
DefaultAssetsFolder=\u9ed8\u8ba4\u4e3a.minecraft/assets\u6587\u4ef6\u5939
|
||||
MakeMCMaximum=\u4f7fMinecraft\u7a97\u53e3\u6700\u5927\u5316
|
||||
MCFolderFormat=\u5c31\u662fMinecraft\u6587\u4ef6\u5939\u683c\u5f0f
|
||||
MakeMCFullscreen=\u4f7fMinecraft\u7a97\u53e3\u5168\u5c4f
|
||||
MCHeight=Minecraft\u7a97\u53e3\u9ad8
|
||||
MCWidth=Minecraft\u7a97\u53e3\u5bbd
|
||||
Personalization=\u4e2a\u6027\u5316
|
||||
MaxPermGen=\u6700\u5927\u6c38\u4e45\u4fdd\u5b58\u533a\u57df\uff08MB\uff09
|
||||
@@ -0,0 +1,236 @@
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
|
||||
\u6e38\u620f\u7248\u672c=\u904a\u6232\u7248\u672c
|
||||
\u8fd9\u4e2aMINECRAFT\u6587\u4ef6\u5939\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u65e7\u7248\u7684\u600e\u4e48\u5bfc\u5165\u561b0V0\u3002=\u9019\u500bminecraft\u8cc7\u6599\u593e\u65e2\u4e0d\u662f1.6\u7248\u4e5f\u4e0d\u662f\u820a\u7248\u7684\u600e\u9ebc\u5c0e\u5165\u561b0v0\u3002
|
||||
\u672a\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u7248\u672c=\u672a\u9078\u4e2d\u4efb\u4f55\u4e00\u500b\u7248\u672c
|
||||
\u5bfc\u5165\u5931\u8d25\:\ {0}=\u5c0e\u5165\u5931\u6557: {0}
|
||||
\u627e\u5230\u540c\u540d\u7684MINECRAFT\u7248\u672c\uff0c\u8bf7\u6362\u7528\u53e6\u4e00\u4e2a\u540d\u79f0=\u627e\u5230\u540c\u540d\u7684Minecraft\u7248\u672c\uff0c\u8acb\u63db\u7528\u53e6\u4e00\u500b\u540d\u7a31
|
||||
\u8bf7\u8f93\u5165\u8be5\u65e7\u7248\u672c\u7684\u540d\u79f0=\u8acb\u8f38\u5165\u8a72\u820a\u7248\u672c\u7684\u540d\u7a31
|
||||
\u627e\u4e0d\u5230MINECRAFT.JAR=\u627e\u4e0d\u5230minecraft.jar
|
||||
\u9009\u62e9MINECRAFT\u8def\u5f84=\u9078\u64c7Minecraft\u8def\u5f91
|
||||
\u542f\u52a8\u5931\u8d25=\u555f\u52d5\u5931\u6557
|
||||
\u590d\u5236\u914d\u7f6e\u6587\u4ef6\u5931\u8d25\:\ =\u8907\u88fd\u914d\u7f6e\u6587\u4ef6\u5931\u6557:
|
||||
\u590d\u5236\u6838\u5fc3\u6a21\u7ec4\u5931\u8d25\:\ =\u8907\u88fd\u6838\u5fc3\u6a21\u7d44\u5931\u6557:
|
||||
\u590d\u5236\u666e\u901a\u6a21\u7ec4\u5931\u8d25\:\ =\u8907\u88fd\u666e\u901a\u6a21\u7d44\u5931\u6557:
|
||||
\u4e0b\u8f7d\u7f3a\u5931\u5e93\uff1a{0}=\u4e0b\u8f09\u7f3a\u5931\u5eab\uff1a{0}
|
||||
\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMINECRAFT\u7248\u672c=\u6c92\u6709\u9078\u64c7\u4efb\u4f55\u4e00\u500bMinecraft\u7248\u672c
|
||||
\u9519\u8bef\u7684MINECRAFT\u8def\u5f84=\u932f\u8aa4\u7684Minecraft\u8def\u5f91
|
||||
\u5173\u4e8e=\u5173\u4e8e
|
||||
\u4e0b\u8f7d=\u4e0b\u8f09
|
||||
\u5bc6\u7801=\u5bc6\u78bc
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52d5\u8a2d\u5b9a
|
||||
\u4e0d\u9650\u5236=\u4e0d\u9650\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u555f\u52d5\u6a21\u5f0f
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5167\u5b58
|
||||
\u6e38\u620f\u540d\u79f0=\u904a\u6232\u540d\u7a31
|
||||
\u6e38\u620f\u8def\u5f84=\u904a\u6232\u8def\u5f91
|
||||
\u5bfc\u5165\u6587\u4ef6\u5939=\u5c0e\u5165\u8cc7\u6599\u593e
|
||||
\u65b0\u5efa=\u65b0\u5efa
|
||||
\u5220\u9664=\u522a\u9664
|
||||
\u7f16\u8f91=\u7de8\u8f2f
|
||||
\u590d\u5236=\u8907\u88fd
|
||||
\u5bfc\u5165\u65e7\u7248\u672c=\u5c0e\u5165\u820a\u7248\u672c
|
||||
\u5236\u4f5c\u4e00\u952e\u542f\u52a8=\u88fd\u4f5c\u4e00\u9375\u555f\u52d5
|
||||
\u51c6\u5907\u4e2d=\u51c6\u5907\u4e2d
|
||||
\u5f00\u59cbMINECRAFT\u4e4b\u65c5!=\u958b\u59cbMinecraft\u4e4b\u65c5!
|
||||
\u5237\u65b0=\u5237\u65b0
|
||||
public_settings=\u5168\u5c40\u8a2d\u5b9a
|
||||
game_download=\u904a\u6232\u4e0b\u8f09
|
||||
\u8bbe\u7f6e\u5931\u8d25\uff1a=\u8a2d\u5b9a\u5931\u6557\uff1a
|
||||
\u7f3a\u5931\u5e93\u4e0b\u8f7d=\u7f3a\u5931\u5eab\u4e0b\u8f09
|
||||
\u9009\u62e9\u80cc\u666f\u8def\u5f84=\u9078\u64c7\u80cc\u666f\u8def\u5f91
|
||||
MineLogin0=\u7db2\u7d61\u932f\u8aa4
|
||||
MineLogin1=\u7528\u6236\u540d\u6216\u5bc6\u78bc\u4e0d\u5408\u6cd5
|
||||
MineLogin2=\u5167\u90e8\u932f\u8aa4
|
||||
MineLogin3=\u7528\u6236\u4e0d\u5b58\u5728
|
||||
MineLogin4=\u9700\u8981\u9a57\u8b49
|
||||
MineLogin5=\u5bc6\u78bc\u932f\u8aa4
|
||||
ForgeMod=Forge mod
|
||||
ModLoaderMod=ModLoader mod
|
||||
Forge=Forge
|
||||
ModLoader=ModLoader
|
||||
Unknown=\u672a\u77e5
|
||||
Mods\u6587\u4ef6\u5939=Mods\u8cc7\u6599\u593e
|
||||
Coremods\u6587\u4ef6\u5939=Coremods\u8cc7\u6599\u593e
|
||||
Mod\u72ec\u7acb\u6587\u4ef6\u5939=Mod\u72ec\u7acb\u8cc7\u6599\u593e
|
||||
\u914d\u7f6e\u6587\u4ef6\u5939=\u914d\u7f6e\u8cc7\u6599\u593e
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u5165\u5931\u6557\uff1a
|
||||
\u9009\u62e9\u5931\u8d25=\u9078\u64c7\u5931\u6557
|
||||
\u63d2\u4ef6\u9519\u8bef\uff1a=\u63d2\u4ef6\u932f\u8aa4\uff1a
|
||||
\u767b\u5f55\u5931\u8d25\uff1a=\u767b\u9304\u5931\u6557\uff1a
|
||||
\u6ca1\u6709\u767b\u5165\u65b9\u5f0f...=\u6c92\u6709\u767b\u5165\u65b9\u5f0f...
|
||||
\u4fdd\u5b58=\u4fdd\u5b58
|
||||
\u767b\u5f55\u6a21\u5f0f=\u767b\u5165\u6a21\u5f0f
|
||||
\u7248\u672c\u7f16\u8f91=\u7248\u672c\u7de8\u8f2f
|
||||
\u7248\u672c\u53f7=\u7248\u672c\u865f
|
||||
\u5bfc\u5165=\u5c0e\u5165
|
||||
\u64cd\u4f5c=\u64cd\u4f5c
|
||||
\u4e0b\u8f7d\u4fe1\u606f=\u4e0b\u8f09\u4fe1\u606f
|
||||
\u5b89\u88c5=\u5b89\u88c5
|
||||
\u6dfb\u52a0=\u6dfb\u52a0
|
||||
\u5168\u90e8\u4e0b\u8f7d=\u5168\u90e8\u4e0b\u8f09
|
||||
\u52a0\u5165MINECRAFT.JAR=\u52a0\u5165minecraft.jar
|
||||
\u7ba1\u7406=\u7ba1\u7406
|
||||
\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4=\u52d5\u614b\u52a0\u8f09\u6a21\u7d44
|
||||
\u5e93=\u5eab
|
||||
AdvancedSettings=\u9ad8\u7d1a\u8a2d\u7f6e
|
||||
\u6700\u5927\u5316=\u6700\u5927\u5316
|
||||
\u68c0\u67e5\u66f4\u65b0=\u6aa2\u67e5\u66f4\u65b0
|
||||
\u67e5\u770b\u65e5\u5fd7=\u67e5\u770b\u65e5\u8a8c
|
||||
\u80cc\u666f\u5730\u5740=\u80cc\u666f\u5730\u5740
|
||||
UNEXPECTED\ EXCEPTION\ LOADING\ =\u610f\u5916\u7684\u7570\u5e38
|
||||
\u5f53\u524d\u662f\u6700\u65b0\u7248\u672c=\u7576\u524d\u662f\u6700\u65b0\u7248\u672c
|
||||
\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762=\u7121\u6cd5\u6253\u958b\u700f\u89bd\u5668\uff0c\u7db2\u5740\u5df2\u7d93\u5fa9\u88fd\u5230\u526a\u8cbc\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52d5\u7c98\u8cbc\u7db2\u5740\u6253\u958b\u9801\u9762
|
||||
\u662f\u5426\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f=\u662f\u5426\u524d\u5f80\u767c\u5e03\u9801\u9762\u66f4\u65b0\uff1f
|
||||
\u66f4\u65b0\u4fe1\u606f\u4e3a\:\ =\u66f4\u65b0\u4fe1\u606f\u70ba:
|
||||
\u6700\u65b0\u7248\u672c\u4e3a\uff1a=\u6700\u65b0\u7248\u672c\u70ba\uff1a
|
||||
\u68c0\u67e5\u66f4\u65b0\u5931\u8d25=\u6aa2\u67e5\u66f4\u65b0\u5931\u6557
|
||||
\u8fde\u63a5\u4e2d=\u9023\u63a5\u4e2d
|
||||
\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5=\u7372\u53d6\u5217\u8868\u5931\u6557\uff0c\u8acb\u5237\u65b0\u91cd\u8a66
|
||||
INVALID\ PLUGIN=\u7121\u6548\u63d2\u4ef6
|
||||
\u65e0\u6cd5\u8fde\u63a5=\u7121\u6cd5\u9023\u63a5
|
||||
\ \u5dee\ ORANGERED=\ \u5dee orangered
|
||||
\ \u8f83\u5dee\ ORANGE=\ \u8f03\u5dee orange
|
||||
\ \u4e2d\ YELLOGREEN=\ \u4e2d yellogreen
|
||||
\ \u8f83\u597d\ BLUE=\ \u8f03\u597d blue
|
||||
\ \u597d\ GREEN=\ \u597d green
|
||||
\u670d\u52a1\u5668{0}\u7684\u56de\u590d\u65e0\u6548=\u670d\u52d9\u5668{0}\u7684\u56de\u590d\u7121\u6548
|
||||
\u63a5\u4e0b\u6765\u5f39\u51fa\u6765\u7684\u7a97\u53e3\u91cc\u8bf7\u9009\u62e9\u8def\u5f84\u4e3a\u6e38\u620f\u8def\u5f84\u3002\u7a0b\u5e8f\u5df2\u7ecf\u5c06\u76ee\u5f55\u590d\u5236\u5230\u4e86\u526a\u8d34\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u91cc\u9009\u62e9\\"...\\"\u6309\u94ae\uff0c\u7c98\u8d34\u8def\u5f84\uff0c\u786e\u5b9a\u5373\u53ef=\u63a5\u4e0b\u4f86\u5f48\u51fa\u4f86\u7684\u7a97\u53e3\u88e1\u8acb\u9078\u64c7\u8def\u5f91\u70ba\u904a\u6232\u8def\u5f91\u3002\u7a0b\u5e8f\u5df2\u7d93\u5c07\u76ee\u9304\u8907\u88fd\u5230\u4e86\u526a\u8cbc\u677f\uff0c\u76f4\u63a5\u5728\u7a97\u53e3\u88e1\u9078\u64c7\\"...\\"\u6309\u9215\uff0c\u7c98\u8cbc\u8def\u5f91\uff0c\u78ba\u5b9a\u5373\u53ef
|
||||
\u65e0\u6cd5\u6253\u5f00\u8d44\u6e90\u7ba1\u7406\u5668\:\ =\u7121\u6cd5\u6253\u958b\u8cc7\u6e90\u7ba1\u7406\u5668:
|
||||
\u63d0\u793a=\u63d0\u793a
|
||||
\u8f93\u5165\u65b0\u7248\u672c\u540d\u79f0=\u8f38\u5165\u65b0\u7248\u672c\u540d\u7a31
|
||||
\u540d\u79f0=\u540d\u7a31
|
||||
\u4fdd\u5b58\u5931\u8d25=\u4fdd\u5b58\u5931\u6557
|
||||
\u4fdd\u5b58\u538b\u7f29\u5305\u5230=\u4fdd\u5b58\u58d3\u7e2e\u5305\u5230
|
||||
\u9009\u62e9\u6750\u8d28\u5305=\u9078\u64c7\u6750\u8cea\u5305
|
||||
\u9009\u62e9\u8d44\u6e90\u5305=\u9078\u64c7\u8cc7\u6e90\u5305
|
||||
\u9009\u62e9\u5e93/\u6a21\u7ec4=\u9078\u64c7\u5eab/\u6a21\u7d44
|
||||
\u6ca1\u6709\u9009\u4e2d\u4efb\u4f55\u4e00\u4e2a\u5e93/\u6a21\u7ec4\u3002=\u6c92\u6709\u9078\u4e2d\u4efb\u4f55\u4e00\u500b\u5eab/\u6a21\u7d44\u3002
|
||||
\u5220\u9664\u5931\u8d25=\u522a\u9664\u5931\u6557
|
||||
\u6dfb\u52a0\u5931\u8d25=\u6dfb\u52a0\u5931\u6557
|
||||
\u9009\u62e9\u6a21\u7ec4=\u9078\u64c7\u6a21\u7d44
|
||||
\u7248\u672c\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a=\u7248\u672c\u540d\u7a31\u4e0d\u80fd\u70ba\u7a7a
|
||||
\u5907\u4efd\u5230=\u5099\u4efd\u5230
|
||||
\u662fCOREODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7ec4=\u662fCoremods\u6587\u4ef6\u593e\u5167\u7684\u6240\u6709\u6838\u5fc3\u6a21\u7d44
|
||||
\u662fMODS\u6587\u4ef6\u5939\u5185\u7684\u6240\u6709\u6a21\u7ec4=\u662fMods\u6587\u4ef6\u593e\u5167\u7684\u6240\u6709\u6a21\u7d44
|
||||
\u901a\u5e38\u662f\u6a21\u7ec4=\u901a\u5e38\u662f\u6a21\u7d44
|
||||
\u4e0b\u79fb=\u4e0b\u79fb
|
||||
\u4e0a\u79fb=\u4e0a\u79fb
|
||||
\u5220\u9664=\u522a\u9664
|
||||
\u589e\u52a0=\u589e\u52a0
|
||||
\u901a\u5e38\u662fFORGE,MODLOADER\u4ee5\u53caMINECRAFT\u6240\u4f9d\u8d56\u7684\u5e93=\u901a\u5e38\u662fForge,Modloader\u4ee5\u53caMinecraft\u6240\u4f9d\u8cf4\u7684\u5eab
|
||||
\u9644\u52a0\u542f\u52a8\u53c2\u6570=\u9644\u52a0\u555f\u52d5\u53c3\u6578
|
||||
\u81ea\u5b9a\u4e49\u5e93\u6587\u4ef6\u5939(LIBRARIES\u6587\u4ef6\u5939)=\u81ea\u5b9a\u7fa9\u5eab\u8cc7\u6599\u593e(libraries\u8cc7\u6599\u593e)
|
||||
\u4e3b\u7c7b=\u4e3b\u7c7b
|
||||
\u81ea\u5b9a\u4e49\u8d44\u6e90\u6587\u4ef6\u5939(ASSETS\u6587\u4ef6\u5939)=\u81ea\u5b9a\u7fa9\u8cc7\u6e90\u8cc7\u6599\u593e(assets\u8cc7\u6599\u593e)
|
||||
\u624b\u52a8\u8bbe\u7f6e=\u624b\u52d5\u8a2d\u5b9a
|
||||
\u4e0d\u5f3a\u5236=\u4e0d\u5f37\u5236
|
||||
32\u4f4d=32\u4f4d
|
||||
64\u4f4d=64\u4f4d
|
||||
\u542f\u52a8\u6a21\u5f0f=\u555f\u52d5\u6a21\u5f0f
|
||||
\u73a9\u5bb6\u540d=\u73a9\u5bb6\u540d
|
||||
1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5bfc\u5165\u7684\u65e7\u7248\u672c=1.6\u53ca\u4ee5\u4e0a\u7248\u672c\u4ee5\u53ca\u5c0e\u5165\u7684\u820a\u7248\u672c
|
||||
\u6700\u5927\u5185\u5b58=\u6700\u5927\u5167\u5b58
|
||||
JAVA\u865a\u62df\u673a\u53c2\u6570=Java\u865b\u64ec\u6a5f\u53c3\u6578
|
||||
JAVA\u8def\u5f84=Java\u8def\u5f91
|
||||
\u5168\u5c4f=\u5168\u5c4f
|
||||
\u5206\u8fa8\u7387=\u5206\u8fa8\u7387
|
||||
\u6e38\u620f\u8def\u5f84=\u904a\u6232\u8def\u5f91
|
||||
\u4ee5\u4e0b\u8bbe\u7f6e\u5b57\u6bb5\u4e3a\u7a7a\u4ee3\u8868\u7740\u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e=\u9664\u540d\u7a31\u4ee5\u4e0b\u5b57\u6bb5\u53ef\u4ee5\u4e0d\u586b
|
||||
\u53d6\u6d88=\u53d6\u6d88
|
||||
\u786e\u5b9a=\u78ba\u5b9a
|
||||
game_download=\u904a\u6232\u4e0b\u8f09
|
||||
public_settings=\u5168\u5c40\u8a2d\u5b9a
|
||||
invalid=\u7121\u6548\u7684
|
||||
invalid_jar=\u7121\u6548\u7684jar\u5305
|
||||
not_a_file=\u4e0d\u662f\u6587\u4ef6
|
||||
not_found=\u627e\u4e0d\u5230minecraft.jar
|
||||
not_readable=minecraft.jar\u4e0d\u53ef\u8b80
|
||||
modified=(\u4fee\u6539\u7684!)
|
||||
\u83b7\u53d6\u4e2d=\u83b7\u53d6\u4e2d
|
||||
\u63d2\u4ef6\u9519\u8bef=\u63d2\u4ef6\u9519\u8bef
|
||||
CannotLoadPluginsBecauseOfAnError=\u65e0\u6cd5\u52a0\u8f7d\u63d2\u4ef6\uff0c\u56e0\u4e3a\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef\u3002
|
||||
CRASH\ REPORT\ DETECTED,\ BUT\ UNKNOWN\ FORMAT\:=Crash report detected, but unknown format:
|
||||
COULDN'T\ OPEN\ CRASH\ REPORT=Couldn't open crash report
|
||||
CRASH\ REPORT\ DETECTED,\ OPENING\:=Crash report detected, opening:
|
||||
MinecraftCrashed=Minecraft\u5d29\u6e83\u4e86\uff01(\u9519\u8bef\u4ee3\u7801:{0})
|
||||
RememberMe=\u8bb0\u4f4f\u6211
|
||||
Logout=\u767b\u51fa
|
||||
ShowIfIsLoaded=\u663e\u793a\u63d2\u4ef6\u662f\u5426\u52a0\u8f7d\uff0c\u70b9\u51fb\u67e5\u770b\u9519\u8bef
|
||||
IsLoaded=\u662f\u5426\u52a0\u8f7d
|
||||
PluginSettings=\u63d2\u4ef6\u8bbe\u7f6e
|
||||
Details=\u4fe1\u606f
|
||||
Authors=\u4f5c\u8005
|
||||
Version=\u7248\u672c
|
||||
Name=\u540d\u79f0
|
||||
CheckUpdate=\u68c0\u67e5\u672c\u542f\u52a8\u5668\u7684\u66f4\u65b0
|
||||
DownloadSource=\u4e0b\u8f7d\u6e90
|
||||
DisableMoveMods=\u7981\u6b62\u7248\u672c\u81ea\u6709\u6a21\u7ec4\uff08\u79fb\u52a8\u6a21\u7ec4\uff09\u529f\u80fd
|
||||
ShowConsoleOutput=\u5c31\u662fMinecraft\u7684\u63a7\u5236\u53f0\u8f93\u51fa
|
||||
MinecraftLocation=Minecraft\u8def\u5f84\uff08\u5373.minecraft\u6587\u4ef6\u5939\uff09
|
||||
MaxMemoryTooltip=\u5141\u8bb8Minecraft\u6700\u591a\u5141\u8bb8\u4f7f\u7528\u7684\u5185\u5b58\uff08\u770b\u4e0d\u61c2\u5c31\u4f7f\u7528\u9ed8\u8ba4\u76841024\u5427\uff09
|
||||
FailedToLoad=\u52a0\u8f7d\u5931\u8d25
|
||||
Loaded=\u5df2\u52a0\u8f7d
|
||||
|
||||
NoCharacter=\u8be5\u5e10\u53f7\u6ca1\u6709\u89d2\u8272
|
||||
LegacyLogin=\u65e7\u7248\u6b63\u7248\u767b\u5f55
|
||||
YggdrasilLogin=\u65b0\u7248\u6b63\u7248\u767b\u5f55
|
||||
PleaseChooseCharacter=\u8bf7\u9009\u62e9\u60a8\u8981\u4f7f\u7528\u7684\u89d2\u8272
|
||||
WrongPassword=\u53ef\u80fd\u662f\u60a8\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
|
||||
OfflineLogin=\u79bb\u7ebf\u6a21\u5f0f
|
||||
GameDownload=\u6e38\u620f\u4e0b\u8f7d
|
||||
IntegrateDownload=\u6574\u5408\u5305\u4e0b\u8f7d
|
||||
AssetsDownload=\u8d44\u6e90\u4e0b\u8f7d
|
||||
Installers=\u81ea\u52a8\u5b89\u88c5
|
||||
WorldSaving=\u5907\u4efd\u5730\u56fe
|
||||
ServerEditor=\u670d\u52a1\u5668\u7f16\u8f91
|
||||
TexturepackEditor=\u6750\u8d28\u5305\u7ba1\u7406
|
||||
Refresh=\u5237\u65b0\u5217\u8868
|
||||
Install=\u5b89\u88c5
|
||||
AssetsType=\u8d44\u6e90\u7c7b\u578b
|
||||
InstallOptifine=\u5b89\u88c5\u9009\u4e2d\u7684Optifine
|
||||
Changelog=\u66f4\u65b0\u4fe1\u606f
|
||||
InstallForge=\u5b89\u88c5\u9009\u4e2d\u7684Forge
|
||||
ModManaging=\u6a21\u7ec4\u7ba1\u7406
|
||||
PluginCenter=\u63d2\u4ef6\u4e2d\u5fc3
|
||||
ExtMods=\u5916\u90e8\u6a21\u7ec4
|
||||
CoreMods=\u6838\u5fc3\u6a21\u7ec4
|
||||
NormalSettings=\u666e\u901a\u8bbe\u7f6e
|
||||
1.6AndAbove=1.6\u53ca\u4ee5\u4e0a
|
||||
1.5AndBelow=1.5\u53ca\u4ee5\u4e0b
|
||||
IsActive=\u6d3b\u52a8
|
||||
Location=\u8def\u5f84
|
||||
Type=\u7c7b\u578b
|
||||
ReleaseTime=\u91ca\u653e\u65f6\u95f4
|
||||
Time=\u53d1\u5e03\u65f6\u95f4
|
||||
Version=\u7248\u672c
|
||||
MCVersion=MC\u7248\u672c
|
||||
IntegrateName=\u6574\u5408\u5305\u540d\u79f0
|
||||
IntegrateVersion=\u6574\u5408\u5305\u7248\u672c
|
||||
ServerName=\u670d\u52a1\u5668\u540d\u79f0
|
||||
HideAddress=\u9690\u85cf\u5730\u5740
|
||||
Address=\u5730\u5740
|
||||
Introduction=\u4ecb\u7ecd
|
||||
Online=\u5728\u7ebf
|
||||
Delay=\u5ef6\u8fdf
|
||||
Clear=\u6e05\u9664
|
||||
Close=\u5173\u95ed
|
||||
Save=\u4fdd\u5b58
|
||||
JoinMinecraftJar=\u52a0\u5165minecraft.jar
|
||||
ExternalMods=\u5916\u90e8\u6a21\u7ec4
|
||||
DynamicLoadingMods=\u52a8\u6001\u52a0\u8f7d\u6a21\u7ec4
|
||||
Libraries=\u5e93
|
||||
TagArguments=\u9644\u52a0\u7ed9\u4e88Minecraft\u7684\u53c2\u6570
|
||||
MainClass=Minecraft\u7684\u4e3b\u7c7b\uff08\u4e0d\u77e5\u9053\u4ec0\u4e48\u610f\u601d\u7684\u8bdd\u4e5f\u5c31\u7528\u4e0d\u4e0a\u4e86\uff09
|
||||
DefaultLibrariesFolder=\u9ed8\u8ba4\u4e3a.minecraft/libraries\u6587\u4ef6\u5939
|
||||
DefaultAssetsFolder=\u9ed8\u8ba4\u4e3a.minecraft/assets\u6587\u4ef6\u5939
|
||||
MakeMCMaximum=\u4f7fMinecraft\u7a97\u53e3\u6700\u5927\u5316
|
||||
MCFolderFormat=\u5c31\u662fMinecraft\u6587\u4ef6\u5939\u683c\u5f0f
|
||||
MakeMCFullscreen=\u4f7fMinecraft\u7a97\u53e3\u5168\u5c4f
|
||||
MCHeight=Minecraft\u7a97\u53e3\u9ad8
|
||||
MCWidth=Minecraft\u7a97\u53e3\u5bbd
|
||||
Personalization=\u4e2a\u6027\u5316
|
||||
MaxPermGen=\u6700\u5927\u6c38\u4e45\u4fdd\u5b58\u533a\u57df\uff08MB\uff09
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.LimitedCapacityList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class JavaProcess {
|
||||
|
||||
private final List<String> commands;
|
||||
private final Process process;
|
||||
private final LimitedCapacityList<String> sysOutLines = new LimitedCapacityList<String>(String.class, 5);
|
||||
|
||||
public JavaProcess(List<String> commands, Process process) {
|
||||
this.commands = commands;
|
||||
this.process = process;
|
||||
}
|
||||
|
||||
public Process getRawProcess() {
|
||||
return this.process;
|
||||
}
|
||||
|
||||
public List<String> getStartupCommands() {
|
||||
return this.commands;
|
||||
}
|
||||
|
||||
public String getStartupCommand() {
|
||||
return this.process.toString();
|
||||
}
|
||||
|
||||
public LimitedCapacityList<String> getSysOutLines() {
|
||||
return this.sysOutLines;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
try {
|
||||
this.process.exitValue();
|
||||
} catch (IllegalThreadStateException ex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getExitCode() {
|
||||
try {
|
||||
return this.process.exitValue();
|
||||
} catch (IllegalThreadStateException ex) {
|
||||
ex.fillInStackTrace();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "JavaProcess[commands=" + this.commands + ", isRunning=" + isRunning() + "]";
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.process.destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.IPlugin;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.OperatingSystems;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.PluginManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Launcher {
|
||||
|
||||
public static boolean disactivedMods = false;
|
||||
public static File gameDir = null;
|
||||
public static boolean ver16 = false, notMove = false;
|
||||
public static String name = null;
|
||||
|
||||
public static void print(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
private static File getLocation() {
|
||||
return gameDir == null ? gameDir = Utils.getLocation() : gameDir;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
print("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
Dimension dimension = null;
|
||||
boolean fullscreen = false;
|
||||
String[] inactiveExtMods = null;
|
||||
String[] inactiveCoreMods = null;
|
||||
String classPath = "";
|
||||
String mainClass = "net.minecraft.client.Minecraft";
|
||||
|
||||
ArrayList<String> cmdList = new ArrayList<String>();
|
||||
int width = 854;
|
||||
int height = 480;
|
||||
|
||||
getLocation();
|
||||
|
||||
for (int n = 0; n < args.length; n++) {
|
||||
String s = args[n];
|
||||
if (s.startsWith("-cp=")) {
|
||||
classPath = s.substring("-cp=".length());
|
||||
print(" ClassPath: " + classPath);
|
||||
} else if (s.startsWith("-windowSize=")) {
|
||||
String o = s.substring("-windowSize=".length());
|
||||
dimension = Utils.parseDimension(o);
|
||||
|
||||
print(" WindowSize: " + (String) o);
|
||||
|
||||
if (dimension == null) {
|
||||
continue;
|
||||
}
|
||||
width = dimension.width;
|
||||
height = dimension.height;
|
||||
} else if (s.equals("-windowFullscreen")) {
|
||||
fullscreen = true;
|
||||
print(" Fullscreen: " + true);
|
||||
} else if (s.startsWith("-inactiveExtMods=")) {
|
||||
s = s.substring("-inactiveExtMods=".length());
|
||||
inactiveExtMods = Utils.tokenize(s, ";");
|
||||
print(" InactiveExtMods: " + s);
|
||||
} else if (s.startsWith("-inactiveCoreMods=")) {
|
||||
s = s.substring("-inactiveCoreMods=".length());
|
||||
inactiveCoreMods = Utils.tokenize(s, ";");
|
||||
print(" InactiveCoreMods: " + s);
|
||||
} else if (s.startsWith("-mainClass=")) {
|
||||
mainClass = s.substring("-mainClass=".length());
|
||||
print(" MainClass: " + mainClass);
|
||||
} else if (s.equals("-ver16")) {
|
||||
ver16 = true;
|
||||
print(" Type: 1.6");
|
||||
} else if (s.equals("-notMove")) {
|
||||
notMove = true;
|
||||
print(" Do not move mods: true");
|
||||
} else if (s.startsWith("-name=")) {
|
||||
name = s.substring("-name=".length());
|
||||
print(" Name: " + name);
|
||||
} else if (s.startsWith("-gameDir=")) {
|
||||
gameDir = new File(s.substring("-gameDir=".length()));
|
||||
print(" GameDir: " + gameDir.getPath());
|
||||
} else {
|
||||
cmdList.add(s);
|
||||
}
|
||||
}
|
||||
if (fullscreen
|
||||
? cmdList.add("--fullscreen")
|
||||
: (width > 0) && (height > 0)) {
|
||||
cmdList.add("--width=" + width);
|
||||
cmdList.add("--height=" + height);
|
||||
}
|
||||
|
||||
String[] cmds = (String[]) cmdList.toArray(new String[cmdList.size()]);
|
||||
|
||||
if (classPath == null) {
|
||||
print("Invalid launcher classpath: " + classPath);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] tokenized = Utils.tokenize(classPath, File.pathSeparator);
|
||||
int len = tokenized.length;
|
||||
File[] files = new File[len];
|
||||
|
||||
URL[] urls = new URL[len];
|
||||
for (int j = 0; j < len; j++) {
|
||||
files[j] = new File(tokenized[j]);
|
||||
urls[j] = new File(tokenized[j]).toURI().toURL();
|
||||
}
|
||||
URLClassLoader loader = new URLClassLoader(urls);
|
||||
Class minecraft = loader.loadClass(mainClass);
|
||||
Method minecraftMain = minecraft.getMethod("main", new Class[]{String[].class});
|
||||
|
||||
moveMods();
|
||||
moveModDir();
|
||||
disactiveMods(inactiveExtMods, inactiveCoreMods);
|
||||
addShutdownHook();
|
||||
|
||||
System.out.println("Invoking minecraft main()");
|
||||
minecraftMain.invoke(null, new Object[]{cmds});
|
||||
|
||||
addForgeModLoaderHandler();
|
||||
|
||||
print("*** Main class main() finished ***");
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void disactiveMods(String[] inactiveExtMods, String[] inactiveCoreMods) {
|
||||
disactiveModsByType(inactiveExtMods, "mods");
|
||||
disactiveModsByType(inactiveCoreMods, "coremods");
|
||||
|
||||
disactivedMods = true;
|
||||
}
|
||||
|
||||
private static void addShutdownHook() {
|
||||
ShutdownHook hook = new ShutdownHook();
|
||||
|
||||
Thread thread = new Thread(hook);
|
||||
Runtime.getRuntime().addShutdownHook(thread);
|
||||
}
|
||||
|
||||
private static void addForgeModLoaderHandler() {
|
||||
MinecraftHandler handler = new MinecraftHandler();
|
||||
Logger localLogger = Logger.getLogger("ForgeModLoader");
|
||||
localLogger.addHandler(handler);
|
||||
}
|
||||
|
||||
private static void disactiveModsByType(String[] paramArrayOfString, String paramString) {
|
||||
restoreModsByType(paramString);
|
||||
|
||||
print("Disable inactive mods: " + paramString);
|
||||
if ((paramArrayOfString == null) || (paramArrayOfString.length <= 0)) {
|
||||
return;
|
||||
}
|
||||
List<String> al = Arrays.asList(paramArrayOfString);
|
||||
File[] files = new File(getLocation(), paramString).listFiles();
|
||||
if (files == null) {
|
||||
print(" No mods: " + paramString);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
if (!file.isDirectory()) {
|
||||
String name = file.getName();
|
||||
|
||||
if ((!al.contains(name))
|
||||
|| ((!name.toLowerCase().endsWith(".zip")) && (!name.toLowerCase().endsWith(".jar")))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String newName = name + "x";
|
||||
File newFile = new File(file.getParentFile(), newName);
|
||||
|
||||
if (newFile.exists()) {
|
||||
newFile.delete();
|
||||
}
|
||||
if (file.renameTo(newFile)) {
|
||||
print(" Disabled: " + name + ", new name: " + newFile.getName());
|
||||
} else {
|
||||
print(" Can not disable: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void restoreModsByType(String paramString) {
|
||||
print("Restoring disabled mods: " + paramString);
|
||||
File[] files = new File(getLocation(), paramString).listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
if (file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String name = file.getName();
|
||||
String lowName = name.toLowerCase();
|
||||
if ((!lowName.endsWith(".zipx")) && (!lowName.endsWith(".jarx"))) {
|
||||
continue;
|
||||
}
|
||||
String newName = name.substring(0, name.length() - 1);
|
||||
|
||||
File newFile = new File(file.getParentFile(), newName);
|
||||
if (newFile.exists()) {
|
||||
file.delete();
|
||||
} else {
|
||||
if (!file.renameTo(newFile)) {
|
||||
print("Can not rename: " + file.getName() + " to: " + newFile.getName() + " in: " + file.getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void restoreMods() {
|
||||
if (disactivedMods) {
|
||||
restoreModsByType("mods");
|
||||
restoreModsByType("coremods");
|
||||
disactivedMods = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void moveMods() {
|
||||
if(notMove) return;
|
||||
String realpa = Utils.addSeparator(gameDir.getPath());
|
||||
java.util.ResourceBundle bundle = C.I18N;
|
||||
moveModsByType(realpa, name, "mods", bundle.getString("复制普通模组失败: "));
|
||||
moveModsByType(realpa, name, "coremods", bundle.getString("复制核心模组失败: "));
|
||||
moveModsByType(realpa, name, "config", bundle.getString("复制配置文件失败: "));
|
||||
}
|
||||
|
||||
static void moveModsByType(String realpa, String name, String type, String error) {
|
||||
if(notMove) return;
|
||||
File file = new File(realpa + "versions" + File.separator + name + File.separator + type);
|
||||
print("Moving mods: " + type);
|
||||
if (file.exists()) {
|
||||
File mf = new File(realpa + type);
|
||||
print("Deleting folder:" + mf.getAbsolutePath());
|
||||
Utils.deleteAll(mf);
|
||||
try {
|
||||
Utils.copyDirectiory(file, mf);
|
||||
print("Copying folder:" + file.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
print(error + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
print("Folder doesn't exist: " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
static void moveBackMods() {
|
||||
if(notMove) return;
|
||||
String realpa = Utils.addSeparator(gameDir.getPath());
|
||||
moveBackModsByType(realpa, "mods");
|
||||
moveBackModsByType(realpa, "coremods");
|
||||
moveBackModsByType(realpa, "config");
|
||||
}
|
||||
|
||||
static void moveBackModsByType(String realpa, String type) {
|
||||
if(notMove) return;
|
||||
if (ver16) {
|
||||
File fmods = new File(realpa + type);
|
||||
if (fmods.exists()) {
|
||||
try {
|
||||
Utils.copyDirectiory(fmods,
|
||||
new File(realpa + "versions" + File.separator
|
||||
+ name + File.separator + type));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void moveModDir() {
|
||||
if(notMove) return;
|
||||
String realpa = Utils.addSeparator(gameDir.getPath());
|
||||
try {
|
||||
print("Moving mod directory");
|
||||
Utils.copyDirectiory(realpa + "versions" + File.separator + name + File.separator + "moddir",
|
||||
realpa);
|
||||
} catch (IOException ex) {
|
||||
print("Failed to move mod directory");
|
||||
Logger.getLogger(Launcher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
static void moveBackModDir() {
|
||||
if(notMove) return;
|
||||
String realpa = Utils.addSeparator(gameDir.getPath());
|
||||
File file = new File(realpa + "versions" + File.separator + name + File.separator + "moddir");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
ArrayList<String> al = Utils.findAllDir(file);
|
||||
for (String s : al) {
|
||||
File fileto = new File(file, s);
|
||||
fileto.delete();
|
||||
File moddir = new File(realpa + s);
|
||||
Utils.copyDirectiory(moddir, fileto);
|
||||
}
|
||||
al = Utils.findAllFile(file);
|
||||
for (String s : al) {
|
||||
File fileto = new File(file, s);
|
||||
fileto.delete();
|
||||
File moddir = new File(realpa + s);
|
||||
Utils.copyFile(moddir, fileto);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
print("Failed to move back mod directory");
|
||||
Logger.getLogger(Launcher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class LauncherOutputStream extends OutputStream {
|
||||
|
||||
private OutputStream a = null;
|
||||
private OutputStream b = null;
|
||||
private boolean c = true;
|
||||
|
||||
public LauncherOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2) {
|
||||
this(paramOutputStream1, paramOutputStream2, true);
|
||||
}
|
||||
|
||||
private LauncherOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2, boolean paramBoolean) {
|
||||
this.a = paramOutputStream1;
|
||||
this.b = paramOutputStream2;
|
||||
this.c = paramBoolean;
|
||||
}
|
||||
|
||||
public final void write(byte[] paramArrayOfByte, int paramInt1, int paramInt2) throws IOException {
|
||||
if (this.a != null) {
|
||||
this.a.write(paramArrayOfByte, paramInt1, paramInt2);
|
||||
}
|
||||
if (this.b != null) {
|
||||
this.b.write(paramArrayOfByte, paramInt1, paramInt2);
|
||||
}
|
||||
if (this.c) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public final void write(byte[] paramArrayOfByte) throws IOException {
|
||||
if (this.a != null) {
|
||||
this.a.write(paramArrayOfByte);
|
||||
}
|
||||
if (this.b != null) {
|
||||
this.b.write(paramArrayOfByte);
|
||||
}
|
||||
if (this.c) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public final void write(int paramInt) throws IOException {
|
||||
if (this.a != null) {
|
||||
this.a.write(paramInt);
|
||||
}
|
||||
if (this.b != null) {
|
||||
this.b.write(paramInt);
|
||||
}
|
||||
if (this.c) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public final void close() throws IOException {
|
||||
flush();
|
||||
|
||||
if (this.a != null) {
|
||||
this.a.close();
|
||||
}
|
||||
if (this.b != null) {
|
||||
this.b.close();
|
||||
}
|
||||
}
|
||||
|
||||
public final void flush() throws IOException {
|
||||
if (this.a != null) {
|
||||
this.a.flush();
|
||||
}
|
||||
if (this.b != null) {
|
||||
this.b.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class LauncherPrintStream extends PrintStream {
|
||||
|
||||
private ModLoaderHandler handler = new ModLoaderHandler();
|
||||
|
||||
public LauncherPrintStream(OutputStream outputStream) {
|
||||
super(outputStream);
|
||||
}
|
||||
|
||||
public final void println(String line) {
|
||||
super.println(line);
|
||||
this.handler.check(line);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import com.seaglasslookandfeel.SeaGlassLookAndFeel;
|
||||
import java.awt.Font;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
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.SSLSession;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.UIManager;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.PluginHandlerType;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.Login;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.MonitorInfoBean;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.MonitorServiceImpl;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.download.URLGet;
|
||||
import org.jackhuang.hellominecraftlauncher.installers.forge.BaseLauncherProfile;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.PluginManager;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.SettingsManager;
|
||||
import org.jackhuang.hellominecraftlauncher.views.MainWindow;
|
||||
import org.jackhuang.metro.MetroLookAndFeel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
// Create an anonymous class to trust all certificates.
|
||||
// This is bad style, you should create a separate class.
|
||||
private static X509TrustManager xtm = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
//System.out.println("---cert: " + chain[0].toString() + ", 认证方式: " + authType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// Create an class to trust all hosts
|
||||
private static HostnameVerifier hnv = new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
//System.out.println("hostname:111111111111111111111 " + hostname);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
// 初始化TLS协议SSLContext
|
||||
// TrustManager
|
||||
SSLContext sslContext = null;
|
||||
|
||||
try {
|
||||
sslContext = SSLContext.getInstance("TLS");
|
||||
X509TrustManager[] xtmArray = new X509TrustManager[]{xtm};
|
||||
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
//打印出一些错误信息和处理这个异常
|
||||
}
|
||||
|
||||
//设置默认的SocketFactory和HostnameVerifier
|
||||
//为javax.net.ssl.HttpsURLConnection
|
||||
if (sslContext != null) {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||
}
|
||||
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(hnv);
|
||||
}
|
||||
public static String launcherName = "Hello Minecraft! Launcher";
|
||||
public static int firstVer = 1, secondVer = 9, thirdVer = 4;
|
||||
public static int minimumLauncherVersion = 13;
|
||||
public static int pluginVersion = 1;
|
||||
|
||||
public static String makeVersion() {
|
||||
return "" + firstVer + '.' + secondVer + '.' + thirdVer;
|
||||
}
|
||||
|
||||
public static String makeTitle() {
|
||||
return launcherName + ' ' + makeVersion();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
PrintStream localPrintStream = System.out;
|
||||
File file = new File(Utils.addSeparator(Utils.currentDir()) + "hmcl.log");
|
||||
FileOutputStream fos = new FileOutputStream(file, false);
|
||||
LauncherOutputStream los = new LauncherOutputStream(localPrintStream, fos);
|
||||
System.setOut(new LauncherPrintStream(los));
|
||||
System.setErr(new LauncherPrintStream(los));
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
try {
|
||||
//UIManager.setLookAndFeel(new SeaGlassLookAndFeel());
|
||||
UIManager.setLookAndFeel(new MetroLookAndFeel());
|
||||
UIManager.getLookAndFeelDefaults().put("defaultFont", new Font("微软雅黑", Font.PLAIN, 12));
|
||||
} catch (Exception ex) {
|
||||
java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
PluginManager.unloadPlugin();
|
||||
}
|
||||
});
|
||||
|
||||
PluginHandlerType.registerPluginHandlerType("LOGIN", Login.class);
|
||||
|
||||
SettingsManager.load();
|
||||
try {
|
||||
PluginManager.preparePlugins();
|
||||
PluginManager.loadPlugin();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
BaseLauncherProfile.tryWriteProfile(SettingsManager.settings.publicSettings.gameDir);
|
||||
|
||||
Thread t = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long m = 0;
|
||||
try {
|
||||
MonitorInfoBean bean = new MonitorServiceImpl().getMonitorInfoBean();
|
||||
m = bean.getTotalMemorySize() / 1024;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
String url = "http://hellominecraftlauncher.duapp.com/count.php?os=" + URLEncoder.encode(System.getProperty("os.name")) + "&mac=" + Utils.getLocalMAC() +
|
||||
"&memory=" + m + "&ver=" + makeVersion();
|
||||
URLGet.get(url);
|
||||
}
|
||||
|
||||
};
|
||||
t.start();
|
||||
|
||||
MainWindow.show(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftHandler extends Handler {
|
||||
|
||||
private boolean restore;
|
||||
|
||||
MinecraftHandler() {
|
||||
restore = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void publish(LogRecord logrecord) {
|
||||
if (restore) {
|
||||
return;
|
||||
}
|
||||
String s = logrecord.getMessage();
|
||||
if (s == null) {
|
||||
return;
|
||||
}
|
||||
if (logrecord.getLevel().intValue() < Level.INFO.intValue()) {
|
||||
return;
|
||||
}
|
||||
if (s.startsWith("Forge Mod Loader has successfully loaded") && s.endsWith("mods")) {
|
||||
restore = true;
|
||||
}
|
||||
if (restore) {
|
||||
Launcher.restoreMods();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void flush() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ModLoaderHandler {
|
||||
|
||||
private boolean ended = false;
|
||||
|
||||
public void check(String line) {
|
||||
if (this.ended) {
|
||||
return;
|
||||
}
|
||||
if (line == null) {
|
||||
return;
|
||||
}
|
||||
if ((!line.equals("Done.")
|
||||
&& (!line.startsWith("Starting up SoundSystem"))
|
||||
&& (!line.startsWith("Loading: net.java.games.input."))
|
||||
&& (!line.startsWith("Found animation info for:"))
|
||||
? 0 : 1) != 0) {
|
||||
this.ended = true;
|
||||
Launcher.restoreMods();
|
||||
}
|
||||
}
|
||||
|
||||
ModLoaderHandler() {
|
||||
super();
|
||||
ended = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jack
|
||||
*/
|
||||
public class Pair<K,T> {
|
||||
public K key;
|
||||
public T value;
|
||||
public Pair(K key, T value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.apis.IPlugin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.PluginManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class ShutdownHook implements Runnable {
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
Launcher.restoreMods();
|
||||
Launcher.moveBackMods();
|
||||
Launcher.moveBackModDir();
|
||||
|
||||
|
||||
try {
|
||||
for(IPlugin p : PluginManager.plugins) {
|
||||
p.minecraftStopped();
|
||||
}
|
||||
} catch(Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Compressor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class PackMinecraftInstaller {
|
||||
|
||||
String dest;
|
||||
ArrayList<String> src;
|
||||
|
||||
public PackMinecraftInstaller(ArrayList<String> src, String dest) {
|
||||
this.dest = dest;
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public void install() {
|
||||
String path = Utils.addSeparator(Utils.currentDir())
|
||||
+ "HMCL-MERGE-TEMP" + File.separator;
|
||||
File file = new File(path);
|
||||
file.mkdirs();
|
||||
for (int i = 0; i < src.size(); i++) {
|
||||
Compressor.unzip(src.get(i), path);
|
||||
}
|
||||
Compressor.zip(path, dest);
|
||||
Utils.deleteAll(file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.forge;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class BaseLauncherProfile {
|
||||
public static String profile = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||
public static void tryWriteProfile(String gameDir) {
|
||||
File file = new File(Utils.addSeparator(gameDir) + "launcher_profiles.json");
|
||||
if(!file.exists())
|
||||
Utils.writeToFile(file, profile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.forge;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.DoneListener;
|
||||
import org.jackhuang.hellominecraftlauncher.download.URLGet;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeFormatThread extends Thread {
|
||||
|
||||
DoneListener<List<ForgeVersion>, Object> lis;
|
||||
int type;
|
||||
|
||||
public ForgeFormatThread(DoneListener<List<ForgeVersion>, Object> lis, int type) {
|
||||
this.lis = lis;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static List<ForgeVersion> formatNew() {
|
||||
|
||||
ArrayList<ForgeVersion> al = new ArrayList<ForgeVersion>();
|
||||
|
||||
try {
|
||||
Document doc = Jsoup.connect("http://files.minecraftforge.net/").get();
|
||||
Elements allbuilds = doc.getElementsByClass("builds");
|
||||
Elements tables = new Elements();
|
||||
for(Element build : allbuilds)
|
||||
tables.addAll(build.getElementsByTag("table"));
|
||||
Elements allforge = new Elements();
|
||||
for(Element table : tables)
|
||||
allforge.addAll(table.getElementsByTag("tr"));
|
||||
tables = null;
|
||||
for(Element e : allforge) {
|
||||
Elements tds = e.getElementsByTag("td");
|
||||
if(tds.isEmpty()) continue;
|
||||
ForgeVersion v = new ForgeVersion();
|
||||
v.ver = tds.get(0).text();
|
||||
v.mcver = tds.get(1).text();
|
||||
v.releasetime = tds.get(2).text();
|
||||
v.installer = new String[2];
|
||||
v.universal = new String[2];
|
||||
v.javadoc = new String[2];
|
||||
v.src = new String[2];
|
||||
v.userdev = new String[2];
|
||||
Elements a = tds.get(3).getElementsByTag("a");
|
||||
String prev = null;
|
||||
for(Element e2 : a) {
|
||||
String href = e2.attributes().get("href").toLowerCase();
|
||||
if(e2.text().toLowerCase().indexOf("changelog") != -1) {
|
||||
v.changelog = href;
|
||||
} else if(prev != null) {
|
||||
int index;
|
||||
if(href.indexOf("adf.ly") != -1) index = 0;
|
||||
else index = 1;
|
||||
if(prev.toLowerCase().indexOf("installer") != -1) {
|
||||
v.installer[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("universal") != -1) {
|
||||
v.universal[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("javadoc") != -1) {
|
||||
v.javadoc[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("src") != -1) {
|
||||
v.src[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("userdev") != -1) {
|
||||
v.userdev[index] = href;
|
||||
}
|
||||
}
|
||||
prev = e2.text();
|
||||
}
|
||||
al.add(v);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ForgeFormatThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
ForgeVersion v = new ForgeVersion();
|
||||
v.ver = "获取失败";
|
||||
al.add(v);
|
||||
}
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
public static List<ForgeVersion> formatLegacy() {
|
||||
|
||||
ArrayList<ForgeVersion> al = new ArrayList<ForgeVersion>();
|
||||
|
||||
try {
|
||||
Document doc = Jsoup.connect("http://files.minecraftforge.net/minecraftforge/index_legacy.html").get();
|
||||
Element allbuilds = doc.getElementById("all_builds");
|
||||
Elements mainTable = allbuilds.getElementsByTag("table");
|
||||
Element table = mainTable.first();
|
||||
Elements allforge = table.getElementsByTag("tr");
|
||||
for(Element e : allforge) {
|
||||
Elements tds = e.getElementsByTag("td");
|
||||
if(tds.isEmpty()) continue;
|
||||
ForgeVersion v = new ForgeVersion();
|
||||
v.ver = tds.get(0).text();
|
||||
v.mcver = tds.get(1).text();
|
||||
v.releasetime = tds.get(2).text();
|
||||
v.installer = new String[2];
|
||||
v.universal = new String[2];
|
||||
v.javadoc = new String[2];
|
||||
Elements a = tds.get(3).getElementsByTag("a");
|
||||
String prev = null;
|
||||
for(Element e2 : a) {
|
||||
String href = e2.attributes().get("href").toLowerCase();
|
||||
if(e2.text().toLowerCase().indexOf("changelog") != -1) {
|
||||
v.changelog = href;
|
||||
} else if(prev != null) {
|
||||
int index;
|
||||
if(href.indexOf("adf.ly") != -1) index = 0;
|
||||
else index = 1;
|
||||
if(prev.toLowerCase().indexOf("installer") != -1) {
|
||||
v.installer[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("universal") != -1) {
|
||||
v.universal[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("javadoc") != -1) {
|
||||
v.javadoc[index] = href;
|
||||
} else
|
||||
if(prev.toLowerCase().indexOf("src") != -1) {
|
||||
v.src[index] = href;
|
||||
}
|
||||
}
|
||||
prev = e2.text();
|
||||
}
|
||||
al.add(v);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//Logger.getLogger(ForgeFormatThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
ForgeVersion v = new ForgeVersion();
|
||||
v.ver = "获取失败";
|
||||
al.add(v);
|
||||
}
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
public static ForgeVersion[] formatBMCL(String url) {
|
||||
String s = URLGet.get(url);
|
||||
return new Gson().fromJson(s, ForgeVersion[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<ForgeVersion> al = null;
|
||||
switch(type) {
|
||||
case 0:
|
||||
al = formatNew();
|
||||
al.addAll(formatLegacy());
|
||||
break;
|
||||
case 1:
|
||||
al = new ArrayList<ForgeVersion>();
|
||||
for(ForgeVersion fv : formatBMCL(C.URL_FORGE_BMCL_NEW)) {
|
||||
al.add(fv);
|
||||
}
|
||||
for(ForgeVersion fv : formatBMCL(C.URL_FORGE_BMCL_LEGACY)) {
|
||||
al.add(fv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(lis != null)
|
||||
lis.onDone(al, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraftlauncher.installers.PackMinecraftInstaller;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeOldInstaller {
|
||||
|
||||
public static void install(String destMinecraftJar, String srcMinecraftJar, String forgeUniversal) {
|
||||
ArrayList<String> al = new ArrayList<String>();
|
||||
al.add(srcMinecraftJar);
|
||||
al.add(forgeUniversal);
|
||||
new PackMinecraftInstaller(al, destMinecraftJar).install();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeVersion {
|
||||
public String vername, ver, mcver, releasetime, changelog;
|
||||
public String[] installer, javadoc, src, universal, userdev;
|
||||
public int typeint;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.optifine;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.DoneListener;
|
||||
import org.jackhuang.hellominecraftlauncher.download.URLGet;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptifineFormatDownloadThread extends Thread {
|
||||
|
||||
DoneListener<String, Object> lis;
|
||||
OptifineVersion source;
|
||||
int type;
|
||||
|
||||
public OptifineFormatDownloadThread(DoneListener<String, Object> lis, OptifineVersion source, int type) {
|
||||
this.lis = lis;
|
||||
this.type = type;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public static String format(String source) {
|
||||
|
||||
String url;
|
||||
|
||||
try {
|
||||
Document doc = Jsoup.connect(source).get();
|
||||
Element download = doc.getElementById("Download");
|
||||
Element a = download.getElementsByTag("a").first();
|
||||
url = "http://optifine.net/" + a.attributes().get("href");
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(OptifineFormatThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
OptifineVersion v = new OptifineVersion();
|
||||
url = null;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static String format_bmcl(String source) {
|
||||
String url = "http://bmclapi.bangbang93.com/optifine/" + URLEncoder.encode(source);
|
||||
return URLGet.get(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String url = null;
|
||||
switch(type) {
|
||||
case 0:
|
||||
url = format(source.dl);
|
||||
break;
|
||||
case 1:
|
||||
url = format_bmcl(source.ver);
|
||||
break;
|
||||
}
|
||||
if(lis != null)
|
||||
lis.onDone(url, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.optifine;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.DoneListener;
|
||||
import org.jackhuang.hellominecraftlauncher.download.URLGet;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptifineFormatThread extends Thread {
|
||||
|
||||
DoneListener<List<OptifineVersion>, Object> lis;
|
||||
int type;
|
||||
|
||||
public OptifineFormatThread(DoneListener<List<OptifineVersion>, Object> lis, int type) {
|
||||
this.lis = lis;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static List<OptifineVersion> format(String source) {
|
||||
|
||||
List<OptifineVersion> al = new ArrayList<OptifineVersion>();
|
||||
|
||||
try {
|
||||
Document doc = Jsoup.connect(source).get();
|
||||
Elements downloads = doc.getElementsByClass("downloads");
|
||||
Element table = downloads.first();
|
||||
Elements tds = table.getElementsByTag("td");
|
||||
Element td = tds.first();
|
||||
Elements allopt = td.children();
|
||||
String lasth2 = "", lasth3 = "";
|
||||
for(int i = 0; i < allopt.size(); i++) {
|
||||
Element e = allopt.get(i);
|
||||
String tagName = e.tagName().toLowerCase();
|
||||
if(tagName.indexOf("h3") != -1) {
|
||||
lasth3 = e.text();
|
||||
String[] s = lasth3.split(" ");
|
||||
lasth3 = s[s.length - 1];
|
||||
} else if(tagName.indexOf("h2") != -1) {
|
||||
lasth2 = e.text().split(" ")[1];
|
||||
} else
|
||||
if(tagName.indexOf("table") != -1) {
|
||||
Elements downloadLines = e.getElementsByTag("tr");
|
||||
for(Element downloadLine : downloadLines) {
|
||||
OptifineVersion v = new OptifineVersion();
|
||||
v.type = lasth3;
|
||||
String[] ver = downloadLine.child(0).text().split(" ");
|
||||
if(ver.length < 1) continue;
|
||||
v.ver = ver[ver.length - 1];
|
||||
v.mcver = lasth2;
|
||||
Element mirror = downloadLine.child(2).child(0);
|
||||
v.dl = mirror.attributes().get("href");
|
||||
v.date = downloadLine.child(3).text();
|
||||
al.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
//Logger.getLogger(OptifineFormatThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
OptifineVersion v = new OptifineVersion();
|
||||
v.ver = "获取失败";
|
||||
al.add(v);
|
||||
}
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
public static List<OptifineVersion> format_bmcl(String source) {
|
||||
Gson gson = new Gson();
|
||||
return Arrays.asList(gson.fromJson(URLGet.get(source), OptifineVersion[].class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<OptifineVersion> al;
|
||||
if(type == 0) {
|
||||
al = format(C.URL_OPTIFINE[0]);
|
||||
} else {
|
||||
al = format_bmcl(C.URL_OPTIFINE[1]);
|
||||
}
|
||||
if(lis != null)
|
||||
lis.onDone(al, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.installers.optifine;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptifineVersion {
|
||||
public String dl, ver, mcver, date, type;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.LoginResult;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.OperatingSystems;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.settings.Version;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.SettingsManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class IMinecraftLoader {
|
||||
protected String minecraftJar;
|
||||
protected Version v;
|
||||
protected LoginResult lr;
|
||||
|
||||
public IMinecraftLoader(Version pub, Version ver, LoginResult lr, String minecraftJar) {
|
||||
this.lr = lr;
|
||||
|
||||
this.minecraftJar = minecraftJar;
|
||||
v = new Version(ver);
|
||||
if(Utils.isEmpty(ver.gameDir)) v.gameDir = Utils.addSeparator(pub.gameDir);
|
||||
if(Utils.isEmpty(ver.gameAssets)) v.gameAssets = pub.gameAssets;
|
||||
if(Utils.isEmpty(v.gameAssets)) v.gameAssets = v.gameDir + "assets";
|
||||
if(Utils.isEmpty(ver.gameLibraries)) v.gameLibraries = pub.gameLibraries;
|
||||
if(Utils.isEmpty(ver.height)) v.height = pub.height;
|
||||
if(Utils.isEmpty(ver.javaArgs)) v.javaArgs = pub.javaArgs;
|
||||
if(Utils.isEmpty(ver.javaDir)) v.javaDir = pub.javaDir;
|
||||
if(Utils.isEmpty(ver.mainClass)) v.mainClass = pub.mainClass;
|
||||
if(Utils.isEmpty(ver.maxMemory)) v.maxMemory = pub.maxMemory;
|
||||
if(Utils.isEmpty(ver.name)) v.name = pub.name;
|
||||
if(Utils.isEmpty(ver.width)) v.width = pub.width;
|
||||
if(Utils.isEmpty(ver.minecraftArguments)) v.minecraftArguments = pub.minecraftArguments;
|
||||
}
|
||||
|
||||
public List<String> makeLaunchingCommand() {
|
||||
System.out.println("*** Making Minecraft Launching Command ***");
|
||||
|
||||
ArrayList<String> res = new ArrayList<String>();
|
||||
String java;
|
||||
if(!Utils.isEmpty(v.javaDir.trim()))
|
||||
{
|
||||
if(Utils.os() == OperatingSystems.WINDOWS) {
|
||||
File file = new File(Utils.addSeparator(v.javaDir) + "javaw.exe");
|
||||
if(file.exists() && file.isFile())
|
||||
java = "javaw.exe";
|
||||
else
|
||||
java = "java.exe";
|
||||
} else {
|
||||
java = "java";
|
||||
}
|
||||
java = Utils.addSeparator(v.javaDir) + java;
|
||||
}
|
||||
else
|
||||
java = Utils.getJavaDir();
|
||||
System.out.println("Java path: " + java);
|
||||
res.add(java);
|
||||
|
||||
if(!Utils.isEmpty(v.javaArgs.trim()))
|
||||
{
|
||||
System.out.println("Java args: " + v.javaArgs);
|
||||
res.add(v.javaArgs);
|
||||
}
|
||||
res.add("-Xincgc");
|
||||
if(!Utils.isEmpty(v.maxMemory))
|
||||
{
|
||||
System.out.println("Memory: " + v.maxMemory);
|
||||
res.add("-Xmx" + v.maxMemory + "m");
|
||||
}
|
||||
|
||||
makeJavaLibraryPath(res);
|
||||
|
||||
res.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
|
||||
res.add("-Dfml.ignorePatchDiscrepancies=true");
|
||||
res.add("-Dsun.java2d.noddraw=true");
|
||||
res.add("-Dsun.java2d.pmoffscreen=false");
|
||||
res.add("-Dsun.java2d.d3d=false");
|
||||
res.add("-Dsun.java2d.opengl=false");
|
||||
if(Utils.os() != OperatingSystems.WINDOWS)
|
||||
{
|
||||
String base = new File(v.gameDir).getParent();
|
||||
System.out.println("Base folder: " + base);
|
||||
res.add("-Duser.home=" + base);
|
||||
}
|
||||
|
||||
res.add("-cp");
|
||||
|
||||
res.add(Utils.parseParams("", Utils.getURL(), File.pathSeparator));
|
||||
res.add("org.jackhuang.hellominecraftlauncher.Launcher");
|
||||
|
||||
makeSelf(res);
|
||||
|
||||
if(!Utils.isEmpty(v.height) && !Utils.isEmpty(v.width))
|
||||
{
|
||||
res.add("-windowSize=" + v.width + "x" + v.height);
|
||||
}
|
||||
|
||||
if(v.fullscreen)
|
||||
res.add("-windowFullscreen");
|
||||
|
||||
if(v.inactiveCoreMods != null && !v.inactiveCoreMods.isEmpty()) {
|
||||
String s = "-inactiveCoreMods=" + Utils.parseParams(
|
||||
"",
|
||||
v.inactiveCoreMods.toArray(), File.pathSeparator
|
||||
);
|
||||
res.add(s);
|
||||
}
|
||||
|
||||
if(v.inactiveExtMods != null && !v.inactiveExtMods.isEmpty()) {
|
||||
String s = "-inactiveExtMods=" + Utils.parseParams(
|
||||
"",
|
||||
v.inactiveExtMods.toArray(), File.pathSeparator);
|
||||
res.add(s);
|
||||
}
|
||||
|
||||
if(!Utils.isEmpty(v.minecraftArguments))
|
||||
{
|
||||
String[] splitted2 = Utils.tokenize(v.minecraftArguments);
|
||||
res.addAll(Arrays.asList(splitted2));
|
||||
}
|
||||
|
||||
res.add("-gameDir=" + v.gameDir);
|
||||
if(SettingsManager.settings.disableMoveMods)
|
||||
res.add("-notMove");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
protected abstract void makeJavaLibraryPath(List<String> list);
|
||||
|
||||
/**
|
||||
* You must do these things:<br />
|
||||
* 1 minecraft class path<br />
|
||||
* 2 main class<br />
|
||||
* 3 minecraft arguments<br />
|
||||
* @param list the command list you shoud edit.
|
||||
*/
|
||||
protected abstract void makeSelf(List<String> list);
|
||||
|
||||
public Version getUserVersion()
|
||||
{
|
||||
return v;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Latest {
|
||||
|
||||
public String snapshot, release;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LaunchRequest {
|
||||
|
||||
public boolean windowMaximized;
|
||||
public boolean windowFullscreen;
|
||||
public boolean showLog;
|
||||
public int width, height;
|
||||
public String classPath;
|
||||
|
||||
public String[] inactiveExtMods, inactiveCoreMods;
|
||||
public List<String> minecraftArguments;
|
||||
public List<String> launchStrings;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraftlauncher.settings.Version;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.LoginResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftLoader extends IMinecraftLoader {
|
||||
private MinecraftVersion version;
|
||||
String text;
|
||||
|
||||
public MinecraftLoader(MinecraftVersion mvt, Version pub, Version ver, LoginResult lr, String minecraftJar)
|
||||
{
|
||||
super(pub, ver, lr, minecraftJar);
|
||||
version = mvt;
|
||||
for(int i = 0; i < version.libraries.size(); i++)
|
||||
{
|
||||
MinecraftLibrary l = version.libraries.get(i);
|
||||
String str = l.name;
|
||||
String[] s = str.split(":");
|
||||
str = s[0];
|
||||
str = str.replace('.', File.separatorChar);
|
||||
if(l.natives == null)
|
||||
str += File.separator + s[1] + File.separator + s[2] +
|
||||
File.separator + s[1] + '-' + s[2] + ".jar";
|
||||
else
|
||||
{
|
||||
str += File.separator + s[1] + File.separator + s[2] +
|
||||
File.separator + s[1] + '-' + s[2] + '-';
|
||||
str += l.getNative();
|
||||
str += ".jar";
|
||||
}
|
||||
l.formatted = str;
|
||||
version.libraries.set(i, l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeJavaLibraryPath(List<String> res) {
|
||||
String library = "-Djava.library.path=";
|
||||
library += Utils.addSeparator(v.gameDir) + "versions" +
|
||||
File.separator + getVersion().id + File.separator + getVersion().id +
|
||||
"-natives";
|
||||
res.add(library);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeSelf(List<String> res)
|
||||
{
|
||||
String realpa = Utils.addSeparator(v.gameDir);
|
||||
String library = "-cp=";
|
||||
String librariespath = realpa + "libraries" + File.separator;
|
||||
if(!v.gameLibraries.equals("")) librariespath = v.gameLibraries;
|
||||
if(v.firstLoadLibraries != null)
|
||||
for(int i = 0; i < v.firstLoadLibraries.size(); i++)
|
||||
if(v.firstLoadLibrariesIsActive == null || v.firstLoadLibrariesIsActive.get(i))
|
||||
library += v.firstLoadLibraries.get(i) + File.pathSeparator;
|
||||
for(int i = 0; i < getVersion().libraries.size(); i++)
|
||||
{
|
||||
MinecraftLibrary l = getVersion().libraries.get(i);
|
||||
if(l.allow())
|
||||
{
|
||||
library += librariespath + l.formatted + File.pathSeparator;
|
||||
}
|
||||
}
|
||||
library += minecraftJar + File.pathSeparator;
|
||||
if(v.lastLoadLibraries != null)
|
||||
for(int i = 0; i < v.lastLoadLibraries.size(); i++)
|
||||
if(v.lastLoadLibrariesIsActive == null || v.lastLoadLibrariesIsActive.get(i))
|
||||
library += v.lastLoadLibraries.get(i) + File.pathSeparator;
|
||||
library = library.substring(0, library.length() - File.pathSeparator.length());
|
||||
res.add(library);
|
||||
String mainClass;
|
||||
if(Utils.isEmpty(v.mainClass))
|
||||
mainClass = getVersion().mainClass;
|
||||
else
|
||||
mainClass = v.mainClass;
|
||||
System.out.println("Main class: " + mainClass);
|
||||
res.add("-mainClass=" + mainClass);
|
||||
|
||||
|
||||
String arg = getVersion().minecraftArguments;
|
||||
String[] splitted = Utils.tokenize(arg);
|
||||
for(String t : splitted) {
|
||||
t = t.replace("${auth_player_name}", lr.username);
|
||||
t = t.replace("${auth_session}", lr.session);
|
||||
t = t.replace("${auth_uuid}", lr.userId);
|
||||
t = t.replace("${version_name}", getVersion().id);
|
||||
t = t.replace("${game_directory}", v.gameDir);
|
||||
t = t.replace("${game_assets}", v.gameAssets);
|
||||
t = t.replace("${assets_root}", v.gameAssets);
|
||||
t = t.replace("${auth_access_token}", lr.accessToken);
|
||||
t = t.replace("${user_type}", lr.userType);
|
||||
if(getVersion().assets != null)
|
||||
t = t.replace("${assets_index_name}", getVersion().assets);
|
||||
t = t.replace("${user_properties}", lr.userProperties);
|
||||
res.add(t);
|
||||
}
|
||||
|
||||
if(res.indexOf("--gameDir") != -1 && res.indexOf("--workDir") != -1) {
|
||||
res.add("--workDir");
|
||||
res.add(v.gameDir);
|
||||
}
|
||||
|
||||
res.add("-ver16");
|
||||
res.add("-name=" + v.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the version
|
||||
*/
|
||||
public MinecraftVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version the version to set
|
||||
*/
|
||||
public void setVersion(MinecraftVersion version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.LoginResult;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.settings.Version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftOldLoader extends IMinecraftLoader {
|
||||
|
||||
public MinecraftOldLoader(Version pub, Version ver, LoginResult lr, String minecraftJar)
|
||||
{
|
||||
super(pub, ver, lr, minecraftJar);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeJavaLibraryPath(List<String> res) {
|
||||
res.add("-Djava.library.path=" + v.gameDir + "bin" + File.separator + "natives");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeSelf(List<String> res)
|
||||
{
|
||||
String library = "-cp=";
|
||||
if(v.firstLoadLibraries != null)
|
||||
for(int i = 0; i < v.firstLoadLibraries.size(); i++)
|
||||
if(v.firstLoadLibrariesIsActive == null || v.firstLoadLibrariesIsActive.get(i))
|
||||
library += v.firstLoadLibraries.get(i) + File.pathSeparator;
|
||||
library += v.gameDir + "bin" + File.separator + "jinput.jar" + File.pathSeparator +
|
||||
v.gameDir + "bin" + File.separator + "lwjgl.jar" + File.pathSeparator +
|
||||
v.gameDir + "bin" + File.separator + "lwjgl_util.jar" + File.pathSeparator;
|
||||
library += minecraftJar + File.separator;
|
||||
if(v.lastLoadLibraries != null)
|
||||
for(int i = 0; i < v.lastLoadLibraries.size(); i++)
|
||||
if(v.lastLoadLibrariesIsActive == null || v.lastLoadLibrariesIsActive.get(i))
|
||||
library += v.lastLoadLibraries.get(i) + File.pathSeparator;
|
||||
library = library.substring(0, library.length() - File.pathSeparator.length());
|
||||
res.add(library);
|
||||
String mainClass;
|
||||
if(Utils.isEmpty(v.mainClass))
|
||||
mainClass = "net.minecraft.client.Minecraft";
|
||||
else
|
||||
mainClass = v.mainClass;
|
||||
System.out.println("Main class: " + mainClass);
|
||||
res.add("-mainClass=" + mainClass);
|
||||
|
||||
res.add(lr.username);
|
||||
res.add(lr.session);
|
||||
|
||||
res.add("--workDir");
|
||||
res.add(v.gameDir);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftVersion;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftVersions {
|
||||
|
||||
public ArrayList<MinecraftVersion> versions;
|
||||
public Latest latest;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftVersionsLoader {
|
||||
|
||||
String JSON;
|
||||
Gson gson;
|
||||
private MinecraftVersions versions;
|
||||
|
||||
public MinecraftVersionsLoader(String j) {
|
||||
gson = new Gson();
|
||||
|
||||
JSON = j;
|
||||
versions = gson.fromJson(JSON, MinecraftVersions.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the versions
|
||||
*/
|
||||
public MinecraftVersions getVersions() {
|
||||
return versions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders.packages;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Packages {
|
||||
public String author, mcversion, version, name, type;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders.serverlist;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ServerInfo {
|
||||
public String name, address;
|
||||
public boolean isHide;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.loaders.serverlist;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import sun.misc.BASE64Decoder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ServerList {
|
||||
public static String address = "AmlwAA==";
|
||||
public static String header = "CgAACQAHc2VydmVycwoAAA==";
|
||||
public static String hideAddress = "AAtoaWRlQWRkcmVzcw==";
|
||||
public static String name = "AARuYW1lAA==";
|
||||
|
||||
public ArrayList<ServerInfo> list;
|
||||
|
||||
public File file;
|
||||
|
||||
public ServerList(File file) {
|
||||
|
||||
this.file = file;
|
||||
if(!file.exists())
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
this.list = new ArrayList<ServerInfo>();
|
||||
|
||||
try {
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
byte[] header = new byte[0x13];
|
||||
stream.read(header, 0, header.length);
|
||||
if(stream.available() < 5) {
|
||||
stream.close();
|
||||
return;
|
||||
}
|
||||
while(stream.available() > 0) {
|
||||
byte[] hideAddress = new byte[13];
|
||||
stream.read(hideAddress, 0, hideAddress.length);
|
||||
boolean isHide = stream.read() == 1 ? true : false;
|
||||
byte[] name = new byte[9];
|
||||
stream.read(name, 0, name.length);
|
||||
ArrayList<Byte> nameList = new ArrayList<Byte>(20);
|
||||
byte ch = (byte) stream.read();
|
||||
while(ch != 0) {
|
||||
if(ch == -1) break;
|
||||
nameList.add(ch);
|
||||
ch = (byte) stream.read();
|
||||
}
|
||||
if(ch == -1) break;
|
||||
byte[] names = new byte[nameList.size()];
|
||||
for(int i = 0; i < nameList.size(); i++) {
|
||||
names[i] = nameList.get(i);
|
||||
}
|
||||
String Name = new String(names);
|
||||
byte[] address = new byte[5];
|
||||
stream.read(address, 0, address.length);
|
||||
ArrayList<Byte> AddRess = new ArrayList<Byte>(20);
|
||||
ch = (byte) stream.read();
|
||||
while(ch != 0) {
|
||||
if(ch == -1) break;
|
||||
AddRess.add(ch);
|
||||
ch = (byte) stream.read();
|
||||
}
|
||||
if(ch == -1) break;
|
||||
byte[] addresses = new byte[AddRess.size()];
|
||||
for(int i = 0; i < AddRess.size(); i++) {
|
||||
addresses[i] = AddRess.get(i);
|
||||
}
|
||||
String Address = new String(addresses);
|
||||
ServerInfo info = new ServerInfo();
|
||||
info.address = Address;
|
||||
info.isHide = isHide;
|
||||
info.name = Name;
|
||||
list.add(info);
|
||||
if(stream.read() == 0)
|
||||
break;
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void write() {
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(file);
|
||||
BASE64Decoder decoder = new BASE64Decoder();
|
||||
stream.write(decoder.decodeBuffer(header));
|
||||
int p = 0;
|
||||
stream.write(0);
|
||||
stream.write(list.size());
|
||||
stream.write(1);
|
||||
for(ServerInfo info : list) {
|
||||
p++;
|
||||
stream.write(decoder.decodeBuffer(hideAddress));
|
||||
if(info.isHide)
|
||||
stream.write(1);
|
||||
else
|
||||
stream.write(0);
|
||||
stream.write(8);
|
||||
stream.write(decoder.decodeBuffer(name));
|
||||
stream.write(info.name.length());
|
||||
stream.write(info.name.getBytes());
|
||||
stream.write(new byte[]{8, 0});
|
||||
stream.write(decoder.decodeBuffer(address));
|
||||
stream.write(info.address.length());
|
||||
stream.write(info.address.getBytes());
|
||||
stream.write(0);
|
||||
if(p != list.size())
|
||||
stream.write(1);
|
||||
else
|
||||
stream.write(0);
|
||||
}
|
||||
stream.close();
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeEmptyFile(File path) {
|
||||
try {
|
||||
FileOutputStream serverdat = new FileOutputStream(path);
|
||||
BASE64Decoder decoder = new BASE64Decoder();
|
||||
byte[] writes = decoder.decodeBuffer(header);
|
||||
serverdat.write(writes, 0, writes.length);
|
||||
serverdat.write(0);
|
||||
serverdat.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ServerList.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.models;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ControllerAction<T> {
|
||||
/**
|
||||
* -1 - NULL
|
||||
* 1 - delete version<br />
|
||||
* 2 - new version<br />
|
||||
* 3 - copy version<br />
|
||||
* 4 - import version<br />
|
||||
* 5 - import folder<br />
|
||||
* 6 - cannot find minecraft.jar<br />
|
||||
* 7 - find the same name in the list<br />
|
||||
*/
|
||||
int action;
|
||||
T content;
|
||||
|
||||
public ControllerAction(int action, T content) {
|
||||
this.action = action;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.models;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.apis.version.MinecraftVersion;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class VersionCopier {
|
||||
|
||||
public static boolean copy(String gameDir, String fromName, String toName) {
|
||||
gameDir = Utils.addSeparator(gameDir);
|
||||
File fromDir = new File(gameDir + fromName + File.separator);
|
||||
if(!fromDir.exists()) return false;
|
||||
File toDir = new File(gameDir + toName + File.separator);
|
||||
toDir.mkdirs();
|
||||
File fromMinecraftJar = new File(gameDir + fromName + File.separator + fromName + ".jar");
|
||||
File toMinecraftJar = new File(gameDir + fromName + File.separator + toName + ".jar");
|
||||
File fromMinecraftJson = new File(gameDir + fromName + File.separator + fromName + ".json");
|
||||
File toMinecraftJson = new File(gameDir + fromName + File.separator + toName + ".json");
|
||||
File fromMinecraftMods = new File(gameDir + fromName + File.separator + "mods" + File.separator);
|
||||
File toMinecraftMods = new File(gameDir + fromName + File.separator + "mods" + File.separator);
|
||||
File fromMinecraftCoreMods = new File(gameDir + fromName + File.separator + "coremods" + File.separator);
|
||||
File toMinecraftCoreMods = new File(gameDir + fromName + File.separator + "coremods" + File.separator);
|
||||
File fromMinecraftConfig = new File(gameDir + fromName + File.separator + "config" + File.separator);
|
||||
File toMinecraftConfig = new File(gameDir + fromName + File.separator + "config" + File.separator);
|
||||
try {
|
||||
Utils.copyFile(fromMinecraftJar, toMinecraftJar);
|
||||
String str = Utils.readToEnd(fromMinecraftJson);
|
||||
Gson gson = new Gson();
|
||||
MinecraftVersion v = gson.fromJson(str, MinecraftVersion.class);
|
||||
v.id = toName;
|
||||
Utils.writeToFile(toMinecraftJson, gson.toJson(v));
|
||||
Utils.copyDirectiory(fromMinecraftMods, toMinecraftMods);
|
||||
Utils.copyDirectiory(fromMinecraftCoreMods, toMinecraftCoreMods);
|
||||
Utils.copyDirectiory(fromMinecraftConfig, toMinecraftConfig);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(VersionCopier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.models;
|
||||
|
||||
import java.io.File;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.MinecraftOldVersionIncluder;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.SettingsManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class VersionManager {
|
||||
|
||||
/**
|
||||
* 导入旧版本
|
||||
* @param mcp
|
||||
* @return Controller Action
|
||||
*/
|
||||
public ControllerAction<String> includeOldVersion() {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
fc.setDialogTitle(C.I18N.getString("选择MINECRAFT路径"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.showOpenDialog(null);
|
||||
try {
|
||||
String mcp = fc.getSelectedFile().getCanonicalPath();
|
||||
if (mcp == null || mcp.trim().equals("")) {
|
||||
return new ControllerAction<String>(-1, "");
|
||||
}
|
||||
File file = new File(mcp + File.separator + "bin" + File.separator + "minecraft.jar");
|
||||
if (!file.exists()) {
|
||||
//MessageBox.Show(C.I18N.getString("找不到MINECRAFT.JAR"));
|
||||
return new ControllerAction<String>(6, "");
|
||||
}
|
||||
|
||||
String name = JOptionPane.showInputDialog(C.I18N.getString("请输入该旧版本的名称"));
|
||||
file = new File(Utils.addSeparator(SettingsManager.settings.publicSettings.gameDir)
|
||||
+ "versions" + File.separator + name);
|
||||
if (file.exists()) {
|
||||
//MessageBox.Show(C.I18N.getString("找到同名的MINECRAFT版本,请换用另一个名称"));
|
||||
return new ControllerAction<String>(7, "");
|
||||
}
|
||||
|
||||
MinecraftOldVersionIncluder l = new MinecraftOldVersionIncluder(mcp, name);
|
||||
l.include();
|
||||
|
||||
return new ControllerAction<String>(4, "");
|
||||
} catch (Exception e) {
|
||||
//MessageBox.Show(
|
||||
// java.text.MessageFormat.format(
|
||||
// C.I18N.getString("导入失败: {0}"), new Object[]{e.getMessage()}));
|
||||
return new ControllerAction<String>(0, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.plugin;
|
||||
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.editpanels.SaveWorldPanel;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.Configuration;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.IMinecraftEnvironment;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.IPlugin;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.Plugin;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.PluginHandlerType;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.events.HMCLPluginLoadEvent;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.events.HMCLPluginUnloadEvent;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.events.HMCLPluginVersionChangedEvent;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.IAssetsHandler;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.handlers.Login;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.editpanels.AssetsPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.editpanels.InstallersPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.editpanels.ServerEditPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.editpanels.TexturepackEditPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.LegacyLogin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.LoginPluginSettings;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.MineLogin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.OfflineLogin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.SkinmeLogin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.logins.YggdrasilLogin;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.mainpanels.GameDownloadPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.mainpanels.IntegrateDownloadPanel;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.settings.AssetsMojangLoader;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.settings.AssetsMojangOldLoader;
|
||||
import org.jackhuang.hellominecraftlauncher.plugin.settings.AssetsZipHandler;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.C;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
@Plugin(apiVer = 1, pluginVer = "1.9.4", pluginId = "hmcl", pluginName = "Hello Minecraft! Launcher",
|
||||
authors = "huangyuhui", description = "Too many features.", requires = {})
|
||||
public class HMCLPlugin extends IPlugin {
|
||||
|
||||
YggdrasilLogin yggdrasilLogin;
|
||||
LegacyLogin legacyLogin;
|
||||
OfflineLogin offlineLogin;
|
||||
SkinmeLogin skinmeLogin;
|
||||
MineLogin mineLogin;
|
||||
Configuration<LoginPluginSettings> config;
|
||||
|
||||
public static IMinecraftEnvironment env;
|
||||
|
||||
//assets handlers
|
||||
AssetsZipHandler assets17, assets174, assets173, assets16;
|
||||
AssetsMojangLoader assetsMojang;
|
||||
AssetsMojangLoader assetsBMCL;
|
||||
AssetsMojangOldLoader assetsOldBMCL;
|
||||
|
||||
//Version edit panels
|
||||
SaveWorldPanel saveWorldPanel;
|
||||
ServerEditPanel serverEditPanel;
|
||||
TexturepackEditPanel texturepackEditPanel;
|
||||
InstallersPanel installersPanel;
|
||||
AssetsPanel assetsPanel;
|
||||
|
||||
//Main panels
|
||||
IntegrateDownloadPanel integrateDownloadPanel;
|
||||
GameDownloadPanel gameDownloadPanel;
|
||||
|
||||
@Override
|
||||
public void load(HMCLPluginLoadEvent event) {
|
||||
|
||||
PluginHandlerType.registerPluginHandlerType("ASSETS", IAssetsHandler.class);
|
||||
PluginHandlerType.registerPluginHandlerType("LOGIN", Login.class);
|
||||
String clientToken = event.getMinecraftEnvironment().clientToken();
|
||||
PluginHandlerType login = PluginHandlerType.getType("LOGIN");
|
||||
event.getPluginRegister().registerPluginHandler(login,
|
||||
offlineLogin = new OfflineLogin(clientToken));
|
||||
event.getPluginRegister().registerPluginHandler(login,
|
||||
yggdrasilLogin = new YggdrasilLogin(clientToken));
|
||||
event.getPluginRegister().registerPluginHandler(login,
|
||||
legacyLogin = new LegacyLogin(clientToken));
|
||||
event.getPluginRegister().registerPluginHandler(login,
|
||||
skinmeLogin = new SkinmeLogin(clientToken));
|
||||
event.getPluginRegister().registerPluginHandler(login,
|
||||
mineLogin = new MineLogin(clientToken));
|
||||
config = new Configuration<LoginPluginSettings>(event.getSuggestedConfigurationFile());
|
||||
config.load(LoginPluginSettings.class);
|
||||
if(config.get() != null) {
|
||||
legacyLogin.onLoadSettings(config.get().legacy);
|
||||
yggdrasilLogin.onLoadSettings(config.get().yggdrasil);
|
||||
}
|
||||
|
||||
env = event.getMinecraftEnvironment();
|
||||
assets174 = new AssetsZipHandler("1.7.4(googlecode)", "assets-175.zip", "http://hmcl.googlecode.com/svn/trunk/assets-175.zip");
|
||||
assets173 = new AssetsZipHandler("1.7.3(googlecode)", "assets-174.zip", "http://hmcl.googlecode.com/svn/trunk/assets-174.zip");
|
||||
assets17 = new AssetsZipHandler("1.7.2(googlecode)", "assets-173.zip", "http://hmcl.googlecode.com/svn/trunk/assets-173.zip");
|
||||
assets16 = new AssetsZipHandler("1.6(googlecode)", "assets-164.zip", "http://hmcl.googlecode.com/svn/trunk/assets-164.zip");
|
||||
assetsMojang = new AssetsMojangLoader(C.URL_ASSETS_MOJANG, "1.7.4(Mojang)");
|
||||
assetsBMCL = new AssetsMojangLoader(C.URL_ASSETS_BMCL, "1.7.4(BMCL)");
|
||||
assetsOldBMCL = new AssetsMojangOldLoader(C.URL_OLD_ASSETS_BMCL, "1.6(BMCL)");
|
||||
PluginHandlerType assets = PluginHandlerType.getType("ASSETS");
|
||||
event.getPluginRegister().registerPluginHandler(assets, assets174);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assets173);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assets17);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assets16);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assetsMojang);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assetsBMCL);
|
||||
event.getPluginRegister().registerPluginHandler(assets, assetsOldBMCL);
|
||||
|
||||
saveWorldPanel = new SaveWorldPanel();
|
||||
serverEditPanel = new ServerEditPanel();
|
||||
texturepackEditPanel = new TexturepackEditPanel();
|
||||
installersPanel = new InstallersPanel();
|
||||
assetsPanel = new AssetsPanel();
|
||||
assetsPanel.assetsType = config.get().assetsType;
|
||||
assetsPanel.prepareAssets();
|
||||
event.getUIRegister().addPanelToVersionEdit(saveWorldPanel);
|
||||
event.getUIRegister().addPanelToVersionEdit(serverEditPanel);
|
||||
event.getUIRegister().addPanelToVersionEdit(texturepackEditPanel);
|
||||
event.getUIRegister().addPanelToVersionEdit(installersPanel);
|
||||
event.getUIRegister().addPanelToVersionEdit(assetsPanel);
|
||||
|
||||
integrateDownloadPanel = new IntegrateDownloadPanel();
|
||||
gameDownloadPanel = new GameDownloadPanel();
|
||||
event.getUIRegister().addPanelToMain(gameDownloadPanel);
|
||||
event.getUIRegister().addPanelToMain(integrateDownloadPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(HMCLPluginUnloadEvent event) {
|
||||
LoginPluginSettings s = new LoginPluginSettings();
|
||||
s.legacy = legacyLogin.onSaveSettings();
|
||||
s.yggdrasil = yggdrasilLogin.onSaveSettings();
|
||||
s.assetsType = assetsPanel.assetsType;
|
||||
config.set(s);
|
||||
try {
|
||||
config.save();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(HMCLPlugin.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void versionChanged(HMCLPluginVersionChangedEvent event) {
|
||||
saveWorldPanel.loadSaves();
|
||||
serverEditPanel.loadServers();
|
||||
texturepackEditPanel.loadPacks();
|
||||
installersPanel.reloadForgeList();
|
||||
installersPanel.reloadOptifineList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraftlauncher.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.IMinecraftEnvironment;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.MinecraftVersionRequest;
|
||||
import org.jackhuang.hellominecraftlauncher.apis.utils.Utils;
|
||||
import org.jackhuang.hellominecraftlauncher.utilities.SettingsManager;
|
||||
import org.jackhuang.hellominecraftlauncher.settings.Version;
|
||||
import org.jackhuang.hellominecraftlauncher.views.MainWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftEnvironment implements IMinecraftEnvironment {
|
||||
|
||||
@Override
|
||||
public String clientToken() {
|
||||
return SettingsManager.settings.clientToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return MainWindow.getInstance().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultGameDir() {
|
||||
return SettingsManager.settings.publicSettings.gameDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersionRequest getMinecraftVersion() {
|
||||
return Utils.minecraftVersion(new File(getVersion().getMinecraftJar()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceType() {
|
||||
return SettingsManager.settings.downloadtype;
|
||||
}
|
||||
|
||||
}
|
||||