Revert
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -27,5 +27,3 @@ HMCSM/build/
|
|||||||
MetroLookAndFeel/build/
|
MetroLookAndFeel/build/
|
||||||
/HMCUtils/build/
|
/HMCUtils/build/
|
||||||
/HMCLaF/build/
|
/HMCLaF/build/
|
||||||
HMCL/version.properties
|
|
||||||
.idea/
|
|
||||||
|
|||||||
@@ -31,6 +31,6 @@
|
|||||||
<license-header>
|
<license-header>
|
||||||
<name>GNU General Public License</name>
|
<name>GNU General Public License</name>
|
||||||
<template>license-header.txt</template>
|
<template>license-header.txt</template>
|
||||||
<property name="organization">HMCLSoft</property>
|
<property name="organization">huangyuhui</property>
|
||||||
</license-header>
|
</license-header>
|
||||||
</gradle-project-properties>
|
</gradle-project-properties>
|
||||||
|
|||||||
17
.travis.yml
17
.travis.yml
@@ -1,10 +1,18 @@
|
|||||||
language: java
|
language: java
|
||||||
sudo: false
|
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- oraclejdk8
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
before_deploy:
|
||||||
|
- git config --global user.email ${GITHUB_EMAIL}
|
||||||
|
- git config --global user.name ${GITHUB_NAME}
|
||||||
|
- git tag ${TRAVIS_BUILD_NUMBER}
|
||||||
|
- git push -q ${REPO} --tags
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: ${DEPLOY_REPO}
|
api_key:
|
||||||
|
secure: lfFEwKtij/s9Ao/SKL7oVdsWcfASshZuwT27gllMrTx1ZQqLCG2I5mGJOp5ukx7lb3y4Tu316nFasLjy9NI3eLXSx9f0w4q+wMf0K5Yj9iOwu/TIn7JkLyHDMQ20qRwGxZplS2WUb669gIRg+l6jUHeTBW+dlTxr0mMa6WHIl8UDpHwfFrGC3i6dL4y6WlDwGl2rYktvOoA/iqvtglBcHuXaL2sDfhp5MXRcYULTIw+b9zmiQXP665DQN+Su5I3gwB4y5X8RH72GAacZn13fEIo5i8UUoHM7UQxM8y8DKSO3avyFCfpUle9+9sErQVW7b6JV1c+AoLWuAhNJLMlUTKarZE7UMqfjvoQHxX5hp2B2WHLEON/UJiGf25HJWx6VhJitE0/odujqnG/umesqki2jMTs6gPcxbc9iBjzUg+ZmFztdtC+Emnni7lpqVVl+Y5hsJRn3Z6rIiNgwmaE0r2OQgAm1vRYFc7jvOdRfyFG+uCRZF6nS56BzJ7dLc0WW8dTgSft6YFll4ZYL6hiI9qiIaBAK948y5HV+6VBWuO3xf/G2CUFbE1Y9qUCjToh3ahxNDzZvXB+rXqvlvNQOi5l8n594oQ61n45qIHSKlMBn9Bxhw29oWT5mo1aYIaNXbpzKam2w4mK0T3VrgTszu/3282wRbNr+VAwdGMfwW1s=
|
||||||
file:
|
file:
|
||||||
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar
|
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar
|
||||||
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
||||||
@@ -13,9 +21,8 @@ deploy:
|
|||||||
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
||||||
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}-MacOSApp.zip
|
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}-MacOSApp.zip
|
||||||
on:
|
on:
|
||||||
repo: mclauncher/HMCL
|
repo: huanghongxun/HMCL
|
||||||
branch: master
|
tags: false
|
||||||
tags: true
|
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
install: echo "skip 'gradle assemble' step"
|
install: echo "skip 'gradle assemble' step"
|
||||||
script: gradle build --continue
|
script: gradle build --continue
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ buildscript {
|
|||||||
classpath 'net.sf.proguard:proguard-gradle:4.10'
|
classpath 'net.sf.proguard:proguard-gradle:4.10'
|
||||||
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
|
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
|
||||||
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
|
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
|
||||||
classpath 'com.google.code.gson:gson:2.2.4'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +38,6 @@ plugins {
|
|||||||
import java.util.jar.JarOutputStream
|
import java.util.jar.JarOutputStream
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
import com.google.gson.JsonParser
|
|
||||||
|
|
||||||
apply plugin: 'launch4j'
|
apply plugin: 'launch4j'
|
||||||
apply plugin: 'me.tatarka.retrolambda'
|
apply plugin: 'me.tatarka.retrolambda'
|
||||||
@@ -48,46 +46,15 @@ if (!hasProperty('mainClass')) {
|
|||||||
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
||||||
}
|
}
|
||||||
|
|
||||||
def readBuildNumber() {
|
|
||||||
def versionPropsFile = file('version.properties')
|
|
||||||
def Properties versionProps = new Properties()
|
|
||||||
|
|
||||||
if (versionPropsFile.canRead()) {
|
|
||||||
versionProps.load(new FileInputStream(versionPropsFile))
|
|
||||||
def code = versionProps['VERSION_CODE'].toInteger()
|
|
||||||
return code.toString()
|
|
||||||
} else {
|
|
||||||
versionPropsFile.createNewFile()
|
|
||||||
|
|
||||||
String url = 'https://api.travis-ci.org/repos/mclauncher/HMCL/branches'
|
|
||||||
def json = new JsonParser().parse(url.toURL().text);
|
|
||||||
if (json.has('branches') && json.get('branches').isJsonArray()) {
|
|
||||||
def branches = json.getAsJsonArray('branches')
|
|
||||||
if (branches != null && branches.size() > 0) {
|
|
||||||
def info = branches.get(0).getAsJsonObject()
|
|
||||||
def code = info.get('number').getAsInt().toString()
|
|
||||||
versionProps['VERSION_CODE'] = code
|
|
||||||
versionProps.store(versionPropsFile.newWriter(), null)
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '233'
|
|
||||||
}
|
|
||||||
|
|
||||||
task cleanVersionFile << {
|
|
||||||
file("version.properties").delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
|
def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
|
||||||
if (buildnumber == null)
|
if (buildnumber == null)
|
||||||
buildnumber = System.getenv("BUILD_NUMBER")
|
buildnumber = System.getenv("BUILD_NUMBER")
|
||||||
if (buildnumber == null)
|
if (buildnumber == null)
|
||||||
buildnumber = readBuildNumber()
|
buildnumber = "233"
|
||||||
|
|
||||||
def versionroot = System.getenv("HMCL_VERSION_ROOT")
|
def versionroot = System.getenv("VERSION_ROOT")
|
||||||
if (versionroot == null)
|
if (versionroot == null)
|
||||||
versionroot = "2.5.3"
|
versionroot = "2.4.1"
|
||||||
|
|
||||||
String mavenGroupId = 'HMCL'
|
String mavenGroupId = 'HMCL'
|
||||||
String mavenVersion = versionroot + '.' + buildnumber
|
String mavenVersion = versionroot + '.' + buildnumber
|
||||||
@@ -173,20 +140,22 @@ jar {
|
|||||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||||
|
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Created-By' : 'Copyright(c) 2013-2016 HMCLSoft.',
|
attributes 'Created-By' : 'Copyright(c) 2013-2016 huangyuhui.',
|
||||||
'Main-Class' : mainClass
|
'Main-Class' : mainClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
launch4j {
|
launch4j {
|
||||||
supportUrl = 'http://www.hmclsoft.com'
|
launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||||
|
//launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
||||||
|
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||||
jreMinVersion = '1.6.0'
|
jreMinVersion = '1.6.0'
|
||||||
|
|
||||||
mainClassName = mainClass
|
mainClassName = mainClass
|
||||||
icon = new File(project.buildDir, '../icon.ico').absolutePath
|
icon = new File(project.buildDir, '../icon.ico').absolutePath
|
||||||
version = mavenVersion
|
version = mavenVersion
|
||||||
downloadUrl = 'http://java.com/download'
|
downloadUrl = 'http://java.com/download'
|
||||||
copyright = "Copyright(c) 2013-2016 HMCLSoft."
|
copyright = "Copyright(c) 2013-2015 huangyuhui."
|
||||||
|
|
||||||
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
|
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
|
||||||
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
|
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
|
||||||
@@ -199,7 +168,6 @@ processResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build.dependsOn cleanVersionFile
|
|
||||||
build.dependsOn makeExecutable
|
build.dependsOn makeExecutable
|
||||||
build.dependsOn makePackGZ
|
build.dependsOn makePackGZ
|
||||||
build.dependsOn macAppCompressed
|
build.dependsOn macAppCompressed
|
||||||
@@ -98,7 +98,7 @@ public class AssetsMojangLoader extends IAssetsHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||||
return new AssetsTask(sourceType.getAssetsDownloadURL(), sourceType.getRetryAssetsDownloadURL());
|
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
|||||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||||
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.func.Function;
|
|
||||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,37 +89,30 @@ public abstract class IAssetsHandler {
|
|||||||
|
|
||||||
protected class AssetsTask extends TaskInfo {
|
protected class AssetsTask extends TaskInfo {
|
||||||
|
|
||||||
ArrayList<Task> tasks;
|
ArrayList<Task> al;
|
||||||
String baseUrl;
|
String u;
|
||||||
String retryBaseUrl;
|
|
||||||
|
|
||||||
public AssetsTask(String url, String retryUrl) {
|
public AssetsTask(String url) {
|
||||||
super(C.i18n("assets.download"));
|
super(C.i18n("assets.download"));
|
||||||
this.baseUrl = url;
|
this.u = url;
|
||||||
this.retryBaseUrl = retryUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeTask() {
|
public void executeTask() {
|
||||||
if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null)
|
if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null)
|
||||||
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
||||||
|
|
||||||
tasks = new ArrayList<>();
|
|
||||||
int max = assetsDownloadURLs.size();
|
int max = assetsDownloadURLs.size();
|
||||||
|
al = new ArrayList<>();
|
||||||
int hasDownloaded = 0;
|
int hasDownloaded = 0;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
String mark = assetsDownloadURLs.get(i);
|
String mark = assetsDownloadURLs.get(i);
|
||||||
String downloadUrl = baseUrl + mark;
|
String url = u + mark;
|
||||||
String downloadRetryUrl = StrUtils.isNotBlank(retryBaseUrl) ? retryBaseUrl + mark : "";
|
|
||||||
File location = assetsLocalNames.get(i);
|
File location = assetsLocalNames.get(i);
|
||||||
|
|
||||||
if (!location.getParentFile().exists() && !location.getParentFile().mkdirs())
|
if (!location.getParentFile().exists() && !location.getParentFile().mkdirs())
|
||||||
HMCLog.warn("Failed to make directories: " + location.getParent());
|
HMCLog.warn("Failed to make directories: " + location.getParent());
|
||||||
|
|
||||||
if (location.isDirectory())
|
if (location.isDirectory())
|
||||||
continue;
|
continue;
|
||||||
|
boolean need = true;
|
||||||
boolean needDownload = true;
|
|
||||||
try {
|
try {
|
||||||
if (location.exists()) {
|
if (location.exists()) {
|
||||||
FileInputStream fis = new FileInputStream(location);
|
FileInputStream fis = new FileInputStream(location);
|
||||||
@@ -130,39 +121,23 @@ public abstract class IAssetsHandler {
|
|||||||
if (contents.get(i).geteTag().equals(sha)) {
|
if (contents.get(i).geteTag().equals(sha)) {
|
||||||
++hasDownloaded;
|
++hasDownloaded;
|
||||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has been downloaded successfully, skipped downloading.");
|
HMCLog.log("File " + assetsLocalNames.get(i) + " has been downloaded successfully, skipped downloading.");
|
||||||
if (ppl != null) {
|
if (ppl != null)
|
||||||
ppl.setProgress(this, hasDownloaded, max);
|
ppl.setProgress(this, hasDownloaded, max);
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
HMCLog.warn("Failed to get hash: " + location, e);
|
HMCLog.warn("Failed to get hash: " + location, e);
|
||||||
needDownload = !location.exists();
|
need = !location.exists();
|
||||||
}
|
}
|
||||||
|
if (need)
|
||||||
if (needDownload) {
|
al.add(new FileDownloadTask(url, location).setTag(mark));
|
||||||
FileDownloadTask fileDownloadTask = new FileDownloadTask(downloadUrl, location);
|
|
||||||
fileDownloadTask.setTag(mark);
|
|
||||||
|
|
||||||
// retry
|
|
||||||
if (StrUtils.isNotBlank(downloadRetryUrl)) {
|
|
||||||
fileDownloadTask.setFailedCallbackReturnsNewURL(new Function<Integer, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(Integer t) {
|
|
||||||
return downloadRetryUrl;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.add(fileDownloadTask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Task> getAfterTasks() {
|
public Collection<Task> getAfterTasks() {
|
||||||
return tasks;
|
return al;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
|
|||||||
public Task downloadAssets(final MinecraftVersion mv) {
|
public Task downloadAssets(final MinecraftVersion mv) {
|
||||||
if (mv == null)
|
if (mv == null)
|
||||||
return null;
|
return null;
|
||||||
return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset())
|
return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()).after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
|
||||||
.after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,12 +29,10 @@ public class DownloadLibraryJob {
|
|||||||
|
|
||||||
public IMinecraftLibrary lib;
|
public IMinecraftLibrary lib;
|
||||||
public String url;
|
public String url;
|
||||||
public String retryUrl;
|
|
||||||
public File path;
|
public File path;
|
||||||
|
|
||||||
public DownloadLibraryJob(IMinecraftLibrary n, String u, String retry, File p) {
|
public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
|
||||||
url = u;
|
url = u;
|
||||||
retryUrl = retry;
|
|
||||||
lib = n;
|
lib = n;
|
||||||
path = IOUtils.tryGetCanonicalFile(p);
|
path = IOUtils.tryGetCanonicalFile(p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ public enum DownloadType {
|
|||||||
Mojang("download.mojang", new MojangDownloadProvider()),
|
Mojang("download.mojang", new MojangDownloadProvider()),
|
||||||
BMCL("download.BMCL", new BMCLAPIDownloadProvider()),
|
BMCL("download.BMCL", new BMCLAPIDownloadProvider()),
|
||||||
//RapidData("download.rapid_data", new RapidDataDownloadProvider()),
|
//RapidData("download.rapid_data", new RapidDataDownloadProvider()),
|
||||||
Curse("Curse CDN", new CurseDownloadProvider()),
|
Curse("Curse CDN", new CurseDownloadProvider());
|
||||||
Dynamic("HMCLSoft", DynamicDownloadProvider.getInstance());
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final IDownloadProvider provider;
|
private final IDownloadProvider provider;
|
||||||
@@ -48,7 +47,7 @@ public enum DownloadType {
|
|||||||
return C.i18n(name);
|
return C.i18n(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DownloadType suggestedDownloadType = Dynamic;
|
private static DownloadType suggestedDownloadType = Mojang;
|
||||||
|
|
||||||
public static DownloadType getSuggestedDownloadType() {
|
public static DownloadType getSuggestedDownloadType() {
|
||||||
return suggestedDownloadType;
|
return suggestedDownloadType;
|
||||||
|
|||||||
@@ -1,161 +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.hellominecraft.launcher.core.download;
|
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
|
||||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author evilwk <evilwk@gmail.com>
|
|
||||||
*/
|
|
||||||
public class DynamicDownloadProvider extends MojangDownloadProvider {
|
|
||||||
|
|
||||||
private static final String PROVIDER_ADDR = "http://client.api.mcgogogo.com:81/provider.php";
|
|
||||||
|
|
||||||
private volatile static DynamicDownloadProvider instance;
|
|
||||||
|
|
||||||
private String versionManifestAddr = null;
|
|
||||||
private String launcherMetaAddr = null;
|
|
||||||
private String launcherAddr = null;
|
|
||||||
|
|
||||||
private String librariesAddr = null;
|
|
||||||
private String assetsAddr = null;
|
|
||||||
|
|
||||||
public void setVersionManifestAddr(String versionManifestAddr) {
|
|
||||||
this.versionManifestAddr = versionManifestAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLauncherMetaAddr(String launcherMetaAddr) {
|
|
||||||
this.launcherMetaAddr = launcherMetaAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLauncherAddr(String launcherAddr) {
|
|
||||||
this.launcherAddr = launcherAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLibrariesAddr(String librariesAddr) {
|
|
||||||
this.librariesAddr = librariesAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAssetsAddr(String assetsAddr) {
|
|
||||||
this.assetsAddr = assetsAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DynamicDownloadProvider() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DynamicDownloadProvider getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
synchronized (DynamicDownloadProvider.class) {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new DynamicDownloadProvider();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRetryAssetsDownloadURL() {
|
|
||||||
return super.getAssetsDownloadURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRetryLibraryDownloadURL() {
|
|
||||||
return super.getLibraryDownloadURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAssetsDownloadURL() {
|
|
||||||
if (StrUtils.isNotBlank(assetsAddr)) {
|
|
||||||
return assetsAddr;
|
|
||||||
}
|
|
||||||
return super.getAssetsDownloadURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLibraryDownloadURL() {
|
|
||||||
if (StrUtils.isNotBlank(librariesAddr)) {
|
|
||||||
return librariesAddr;
|
|
||||||
}
|
|
||||||
return super.getLibraryDownloadURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersionsListDownloadURL() {
|
|
||||||
if (StrUtils.isNotBlank(versionManifestAddr)) {
|
|
||||||
return versionManifestAddr;
|
|
||||||
}
|
|
||||||
return super.getVersionsListDownloadURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getParsedDownloadURL(String str) {
|
|
||||||
if (str != null) {
|
|
||||||
if (StrUtils.isNotBlank(librariesAddr)) {
|
|
||||||
str = str.replace("https://libraries.minecraft.net", librariesAddr);
|
|
||||||
}
|
|
||||||
if (StrUtils.isNotBlank(launcherMetaAddr)) {
|
|
||||||
str = str.replace("https://launchermeta.mojang.com", launcherMetaAddr);
|
|
||||||
}
|
|
||||||
if (StrUtils.isNotBlank(launcherAddr)) {
|
|
||||||
str = str.replace("https://launcher.mojang.com", launcherAddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.getParsedDownloadURL(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init() {
|
|
||||||
new Thread() {
|
|
||||||
|
|
||||||
private String getValue(Map<String, String> addrInfo, String key) {
|
|
||||||
String value = null;
|
|
||||||
do {
|
|
||||||
if (!addrInfo.containsKey(key))
|
|
||||||
continue;
|
|
||||||
value = addrInfo.get(key);
|
|
||||||
} while(false);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
String providerInfo = NetUtils.get(PROVIDER_ADDR);
|
|
||||||
Map<String, String> addrInfo = null;
|
|
||||||
addrInfo = C.GSON.fromJson(providerInfo, new TypeToken<Map<String, String>>() {}.getType());
|
|
||||||
if (addrInfo != null) {
|
|
||||||
setLibrariesAddr(getValue(addrInfo, "libraries"));
|
|
||||||
setAssetsAddr(getValue(addrInfo, "assets"));
|
|
||||||
setLauncherMetaAddr(getValue(addrInfo, "launcherMeta"));
|
|
||||||
setLauncherAddr(getValue(addrInfo, "launcher"));
|
|
||||||
setVersionManifestAddr(getValue(addrInfo, "versionManifest"));
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,10 +47,6 @@ public abstract class IDownloadProvider {
|
|||||||
|
|
||||||
public abstract String getLibraryDownloadURL();
|
public abstract String getLibraryDownloadURL();
|
||||||
|
|
||||||
public String getRetryLibraryDownloadURL() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String getVersionsDownloadURL();
|
public abstract String getVersionsDownloadURL();
|
||||||
|
|
||||||
public abstract String getIndexesDownloadURL();
|
public abstract String getIndexesDownloadURL();
|
||||||
@@ -59,10 +55,6 @@ public abstract class IDownloadProvider {
|
|||||||
|
|
||||||
public abstract String getAssetsDownloadURL();
|
public abstract String getAssetsDownloadURL();
|
||||||
|
|
||||||
public String getRetryAssetsDownloadURL() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For example, minecraft.json/assetIndex/url or
|
* For example, minecraft.json/assetIndex/url or
|
||||||
* minecraft.json/downloads/client/url
|
* minecraft.json/downloads/client/url
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.jackhuang.hellominecraft.launcher.core.GameException;
|
|||||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
|
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.LibraryDownloadInfo;
|
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||||
import org.jackhuang.hellominecraft.util.func.Function;
|
import org.jackhuang.hellominecraft.util.func.Function;
|
||||||
@@ -54,17 +53,14 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
|||||||
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
||||||
if (mv == null)
|
if (mv == null)
|
||||||
return downloadLibraries;
|
return downloadLibraries;
|
||||||
|
|
||||||
MinecraftVersion v = mv.resolve(service.version());
|
MinecraftVersion v = mv.resolve(service.version());
|
||||||
for (IMinecraftLibrary libraryInfo : v.getLibraries())
|
for (IMinecraftLibrary l : v.getLibraries())
|
||||||
if (libraryInfo != null && libraryInfo.allow() && libraryInfo.getDownloadInfo() != null) {
|
if (l != null && l.allow() && l.getDownloadInfo() != null) {
|
||||||
File ff = libraryInfo.getFilePath(service.baseDirectory());
|
File ff = l.getFilePath(service.baseDirectory());
|
||||||
if (!ff.exists()) {
|
if (!ff.exists()) {
|
||||||
LibraryDownloadInfo downloadInfo = libraryInfo.getDownloadInfo();
|
String libURL = l.getDownloadInfo().getUrl(service.getDownloadType());
|
||||||
String downloadUrl = downloadInfo.getUrl(service.getDownloadType());
|
if (libURL != null)
|
||||||
String retryDownloadUrl = downloadInfo.getRetryUrl(service.getDownloadType());
|
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
|
||||||
if (downloadUrl != null)
|
|
||||||
downloadLibraries.add(new DownloadLibraryJob(libraryInfo, downloadUrl, retryDownloadUrl, ff));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return downloadLibraries;
|
return downloadLibraries;
|
||||||
@@ -118,13 +114,10 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Integer repeat) {
|
public String apply(Integer t) {
|
||||||
int index = repeat / 2;
|
return DownloadType.values()[t / 2].getProvider().getVersionsDownloadURL() + suffix;
|
||||||
if (index > DownloadType.values().length) {
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
return DownloadType.values()[index].getProvider().getVersionsDownloadURL() + suffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -42,31 +42,26 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
|||||||
return org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineVersionList.getInstance();
|
return org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
// jars
|
|
||||||
@Override
|
@Override
|
||||||
public String getLibraryDownloadURL() {
|
public String getLibraryDownloadURL() {
|
||||||
return "https://libraries.minecraft.net";
|
return "https://libraries.minecraft.net";
|
||||||
}
|
}
|
||||||
|
|
||||||
// jars
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersionsDownloadURL() {
|
public String getVersionsDownloadURL() {
|
||||||
return "http://s3.amazonaws.com/Minecraft.Download/versions/";
|
return "http://s3.amazonaws.com/Minecraft.Download/versions/";
|
||||||
}
|
}
|
||||||
|
|
||||||
// resource
|
|
||||||
@Override
|
@Override
|
||||||
public String getIndexesDownloadURL() {
|
public String getIndexesDownloadURL() {
|
||||||
return "http://s3.amazonaws.com/Minecraft.Download/indexes/";
|
return "http://s3.amazonaws.com/Minecraft.Download/indexes/";
|
||||||
}
|
}
|
||||||
|
|
||||||
// game versions json
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersionsListDownloadURL() {
|
public String getVersionsListDownloadURL() {
|
||||||
return "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
return "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
// resource
|
|
||||||
@Override
|
@Override
|
||||||
public String getAssetsDownloadURL() {
|
public String getAssetsDownloadURL() {
|
||||||
return "https://resources.download.minecraft.net/";
|
return "https://resources.download.minecraft.net/";
|
||||||
@@ -85,7 +80,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
|||||||
return str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
|
return str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
|
||||||
else if (str.contains("typesafe") || str.contains("scala"))
|
else if (str.contains("typesafe") || str.contains("scala"))
|
||||||
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
|
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
|
||||||
return str.replace("http://files.minecraftforge.net/maven", "http://maven.aliyun.com/nexus/content/groups/public");
|
return str.replace("http://files.minecraftforge.net/maven", "http://maven.oschina.net/content/groups/public");
|
||||||
else
|
else
|
||||||
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
|
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -30,110 +30,91 @@ import org.jackhuang.hellominecraft.util.tasks.Task;
|
|||||||
*/
|
*/
|
||||||
public abstract class InstallerVersionList {
|
public abstract class InstallerVersionList {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh installer versions list from the downloaded content.
|
* Refresh installer versions list from the downloaded content.
|
||||||
*
|
*
|
||||||
* @param versions Minecraft versions you need to refresh
|
* @param versions Minecraft versions you need to refresh
|
||||||
*
|
*
|
||||||
* @throws java.lang.Exception including network exceptions, IO exceptions.
|
* @throws java.lang.Exception including network exceptions, IO exceptions.
|
||||||
*/
|
*/
|
||||||
public abstract Task refresh(String[] versions);
|
public abstract Task refresh(String[] versions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installer name.
|
* Installer name.
|
||||||
*
|
*
|
||||||
* @return installer name.
|
* @return installer name.
|
||||||
*/
|
*/
|
||||||
public abstract String getName();
|
public abstract String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get installers you want.
|
* Get installers you want.
|
||||||
*
|
*
|
||||||
* @param mcVersion the installers to this Minecraft version.
|
* @param mcVersion the installers to this Minecraft version.
|
||||||
*
|
*
|
||||||
* @return cached result.
|
* @return cached result.
|
||||||
*/
|
*/
|
||||||
protected abstract List<InstallerVersion> getVersionsImpl(String mcVersion);
|
protected abstract List<InstallerVersion> getVersionsImpl(String mcVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get installers you want, please cache this method's result to save time.
|
* Get installers you want, please cache this method's result to save time.
|
||||||
*
|
*
|
||||||
* @param mcVersion the installers to this Minecraft version.
|
* @param mcVersion the installers to this Minecraft version.
|
||||||
*
|
*
|
||||||
* @return a copy of the cached data to prevent
|
* @return a copy of the cached data to prevent
|
||||||
* ConcurrentModificationException.
|
* ConcurrentModificationException.
|
||||||
*/
|
*/
|
||||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||||
List<InstallerVersion> a = getVersionsImpl(mcVersion);
|
List<InstallerVersion> a = getVersionsImpl(mcVersion);
|
||||||
if (a == null) {
|
if (a == null)
|
||||||
return null;
|
return null;
|
||||||
} else {
|
else
|
||||||
return new ArrayList<>(a);
|
return new ArrayList<>(a);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static int compareVersion(String verOne, String verTwo) {
|
public static class InstallerVersion implements Comparable<InstallerVersion> {
|
||||||
String[] verInfoOne = verOne.split("\\.");
|
|
||||||
String[] verInfoTwo = verTwo.split("\\.");
|
|
||||||
int idx = 0;
|
|
||||||
int minLength = Math.min(verInfoOne.length, verInfoTwo.length);
|
|
||||||
int diff = 0;
|
|
||||||
while (idx < minLength
|
|
||||||
&& (diff = verInfoOne[idx].length() - verInfoTwo[idx].length()) == 0
|
|
||||||
&& (diff = verInfoOne[idx].compareTo(verInfoTwo[idx])) == 0) {
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
diff = (diff != 0) ? diff : verInfoOne.length - verInfoTwo.length;
|
|
||||||
return (diff == 0) ? 0 : (diff < 0 ? -1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InstallerVersion implements Comparable<InstallerVersion> {
|
public String selfVersion, mcVersion;
|
||||||
|
public String installer, universal;
|
||||||
|
public String changelog;
|
||||||
|
|
||||||
public String selfVersion, mcVersion;
|
public InstallerVersion(String selfVersion, String mcVersion) {
|
||||||
public String installer, universal;
|
this.selfVersion = selfVersion;
|
||||||
public String changelog;
|
this.mcVersion = mcVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public InstallerVersion(String selfVersion, String mcVersion) {
|
@Override
|
||||||
this.selfVersion = selfVersion;
|
public int compareTo(InstallerVersion o) {
|
||||||
this.mcVersion = mcVersion;
|
return selfVersion.compareTo(o.selfVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(InstallerVersion o) {
|
public int hashCode() {
|
||||||
return compareVersion(selfVersion, o.selfVersion);
|
return selfVersion.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(Object obj) {
|
||||||
return selfVersion.hashCode();
|
if (this == obj)
|
||||||
}
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
final InstallerVersion other = (InstallerVersion) obj;
|
||||||
|
return Objects.equals(this.selfVersion, other.selfVersion);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final InstallerVersion other = (InstallerVersion) obj;
|
|
||||||
return Objects.equals(this.selfVersion, other.selfVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
public static class InstallerVersionComparator implements Comparator<InstallerVersion>, Serializable {
|
||||||
|
|
||||||
public static class InstallerVersionComparator implements Comparator<InstallerVersion>, Serializable {
|
private static final long serialVersionUID = 3276198781795213723L;
|
||||||
|
|
||||||
private static final long serialVersionUID = 3276198781795213723L;
|
public static final InstallerVersionComparator INSTANCE = new InstallerVersionComparator();
|
||||||
|
|
||||||
public static final InstallerVersionComparator INSTANCE = new InstallerVersionComparator();
|
@Override
|
||||||
|
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||||
@Override
|
return o2.compareTo(o1);
|
||||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
}
|
||||||
return o2.compareTo(o1);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,13 +76,10 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
|
|||||||
|
|
||||||
for (Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
|
for (Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
|
||||||
String mcver = StrUtils.formatVersion(arr.getKey());
|
String mcver = StrUtils.formatVersion(arr.getKey());
|
||||||
if (mcver == null) {
|
|
||||||
mcver = arr.getKey();
|
|
||||||
}
|
|
||||||
ArrayList<InstallerVersion> al = new ArrayList<>();
|
ArrayList<InstallerVersion> al = new ArrayList<>();
|
||||||
for (int num : arr.getValue()) {
|
for (int num : arr.getValue()) {
|
||||||
MinecraftForgeVersion v = root.number.get(num);
|
MinecraftForgeVersion v = root.number.get(num);
|
||||||
InstallerVersion iv = new InstallerVersion(v.version, v.mcversion);
|
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.mcversion));
|
||||||
for (String[] f : v.files) {
|
for (String[] f : v.files) {
|
||||||
|
|
||||||
String ver = v.mcversion + "-" + v.version;
|
String ver = v.mcversion + "-" + v.version;
|
||||||
@@ -111,7 +108,7 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
|
|||||||
versions.add(iv);
|
versions.add(iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMap.put(mcver, al);
|
versionMap.put(StrUtils.formatVersion(mcver), al);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(versions, new InstallerVersionComparator());
|
Collections.sort(versions, new InstallerVersionComparator());
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ import java.io.File;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.func.Function;
|
|
||||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,20 +49,12 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
|||||||
if (s.length == 3 && s[2].length() > 3)
|
if (s.length == 3 && s[2].length() > 3)
|
||||||
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
|
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
|
||||||
}
|
}
|
||||||
download(new URL(job.url), job.retryUrl, job.path);
|
download(new URL(job.url), job.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void download(URL url, String retryUrl, File filePath) throws Throwable {
|
void download(URL url, File filePath) throws Throwable {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
if (StrUtils.isNotBlank(retryUrl)) {
|
|
||||||
this.failedCallbackReturnsNewURL = new Function<Integer, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(Integer t) {
|
|
||||||
return retryUrl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
super.executeTask();
|
super.executeTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.launcher.core.mod;
|
package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
@@ -62,8 +60,6 @@ public class ModInfo implements Comparable<ModInfo> {
|
|||||||
public String credits;
|
public String credits;
|
||||||
@SerializedName("authorList")
|
@SerializedName("authorList")
|
||||||
public String[] authorList;
|
public String[] authorList;
|
||||||
@SerializedName("authors")
|
|
||||||
public String[] authors;
|
|
||||||
|
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return !location.getName().endsWith(".disabled");
|
return !location.getName().endsWith(".disabled");
|
||||||
@@ -91,8 +87,6 @@ public class ModInfo implements Comparable<ModInfo> {
|
|||||||
public String getAuthor() {
|
public String getAuthor() {
|
||||||
if (authorList != null && authorList.length > 0)
|
if (authorList != null && authorList.length > 0)
|
||||||
return StrUtils.parseParams("", authorList, ", ");
|
return StrUtils.parseParams("", authorList, ", ");
|
||||||
else if (authors != null && authors.length > 0)
|
|
||||||
return StrUtils.parseParams("", authors, ", ");
|
|
||||||
else if (StrUtils.isNotBlank(author))
|
else if (StrUtils.isNotBlank(author))
|
||||||
return author;
|
return author;
|
||||||
else
|
else
|
||||||
@@ -129,30 +123,18 @@ public class ModInfo implements Comparable<ModInfo> {
|
|||||||
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith("litemod");
|
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith("litemod");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Type TYPE = new TypeToken<List<ModInfo>>() {
|
||||||
|
}.getType();
|
||||||
|
|
||||||
private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||||
ModInfo i = new ModInfo();
|
ModInfo i = new ModInfo();
|
||||||
i.location = f;
|
i.location = f;
|
||||||
|
List<ModInfo> m = C.GSON.fromJson(new InputStreamReader(jar.getInputStream(entry), "UTF-8"), TYPE);
|
||||||
InputStreamReader streamReader = new InputStreamReader(jar.getInputStream(entry), "UTF-8");
|
if (m != null && m.size() > 0) {
|
||||||
|
i = m.get(0);
|
||||||
JsonParser parser = new JsonParser();
|
i.location = f;
|
||||||
JsonElement element = parser.parse(streamReader);
|
}
|
||||||
List<ModInfo> m = null;
|
return i;
|
||||||
if (element.isJsonArray()) {
|
|
||||||
m = C.GSON.fromJson(element, new TypeToken<List<ModInfo>>(){}.getType());
|
|
||||||
} else if (element.isJsonObject()) {
|
|
||||||
JsonObject modInfo = element.getAsJsonObject();
|
|
||||||
if (modInfo.has("modList") && modInfo.get("modList").isJsonArray()) {
|
|
||||||
m = C.GSON.fromJson(modInfo.get("modList"), new TypeToken<List<ModInfo>>(){}.getType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m != null && m.size() > 0) {
|
|
||||||
i = m.get(0);
|
|
||||||
i.location = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ModInfo getLiteLoaderModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
private static ModInfo getLiteLoaderModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
|||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||||
|
|
||||||
@@ -36,43 +35,14 @@ public class LibraryDownloadInfo extends GameDownloadInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(DownloadType dt, boolean allowSelf) {
|
public String getUrl(DownloadType dt, boolean allowSelf) {
|
||||||
IDownloadProvider provider = dt.getProvider();
|
String myURL = (forgeURL == null ? dt.getProvider().getLibraryDownloadURL() : forgeURL);
|
||||||
String downloadUrl = (forgeURL == null ? provider.getLibraryDownloadURL() : forgeURL);
|
if (StrUtils.isNotBlank(url) && allowSelf)
|
||||||
if (StrUtils.isNotBlank(url) && allowSelf) {
|
myURL = url;
|
||||||
downloadUrl = url;
|
if (!myURL.endsWith(".jar"))
|
||||||
} // forced replace: Let different download sources into force
|
if (path == null)
|
||||||
return provider.getParsedDownloadURL(getUrlWithBaseUrl(downloadUrl));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRetryUrl(DownloadType dt) {
|
|
||||||
IDownloadProvider provider = dt.getProvider();
|
|
||||||
String retryBaseUrl = provider.getRetryLibraryDownloadURL();
|
|
||||||
|
|
||||||
String downloadUrl = (forgeURL == null ? retryBaseUrl : forgeURL);
|
|
||||||
if (StrUtils.isNotBlank(url) && provider.isAllowedToUseSelfURL()) {
|
|
||||||
downloadUrl = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtils.isBlank(downloadUrl)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadUrl = getUrlWithBaseUrl(downloadUrl);
|
|
||||||
if (downloadUrl.contains("minecraftforge")) { // fix forge url
|
|
||||||
downloadUrl = provider.getParsedDownloadURL(downloadUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return downloadUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getUrlWithBaseUrl(String baseUrl) {
|
|
||||||
if (!baseUrl.endsWith(".jar")) {
|
|
||||||
if (path == null) {
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
else
|
||||||
baseUrl = IOUtils.addURLSeparator(baseUrl) + path.replace('\\', '/');
|
myURL = IOUtils.addURLSeparator(myURL) + path.replace('\\', '/');
|
||||||
}
|
return myURL;
|
||||||
}
|
}
|
||||||
return baseUrl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,122 +31,112 @@ import org.jackhuang.hellominecraft.util.StrUtils;
|
|||||||
*/
|
*/
|
||||||
public class MinecraftLibrary extends IMinecraftLibrary {
|
public class MinecraftLibrary extends IMinecraftLibrary {
|
||||||
|
|
||||||
@SerializedName("rules")
|
@SerializedName("rules")
|
||||||
public ArrayList<Rules> rules;
|
public ArrayList<Rules> rules;
|
||||||
@SerializedName("url")
|
@SerializedName("url")
|
||||||
public String url;
|
public String url;
|
||||||
@SerializedName("natives")
|
@SerializedName("natives")
|
||||||
public Natives natives;
|
public Natives natives;
|
||||||
@SerializedName("extract")
|
@SerializedName("extract")
|
||||||
public Extract extract;
|
public Extract extract;
|
||||||
@SerializedName("downloads")
|
@SerializedName("downloads")
|
||||||
public LibrariesDownloadInfo downloads;
|
public LibrariesDownloadInfo downloads;
|
||||||
|
|
||||||
public MinecraftLibrary(String name) {
|
public MinecraftLibrary(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
|
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
|
||||||
super(name);
|
super(name);
|
||||||
this.rules = (rules == null) ? null : (ArrayList<Rules>) rules.clone();
|
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.natives = (natives == null) ? null : (Natives) natives.clone();
|
this.natives = natives == null ? null : (Natives) natives.clone();
|
||||||
this.extract = (extract == null) ? null : (Extract) extract.clone();
|
this.extract = extract == null ? null : (Extract) extract.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean allow() {
|
* is the library allowed to load.
|
||||||
if (rules != null) {
|
*
|
||||||
boolean flag = false;
|
* @return
|
||||||
for (Rules r : rules) {
|
*/
|
||||||
if ("disallow".equals(r.action())) {
|
@Override
|
||||||
return false;
|
public boolean allow() {
|
||||||
} else if ("allow".equals(r.action())) {
|
if (rules != null) {
|
||||||
flag = true;
|
boolean flag = false;
|
||||||
}
|
for (Rules r : rules)
|
||||||
}
|
if ("disallow".equals(r.action()))
|
||||||
return flag;
|
return false;
|
||||||
}
|
else if ("allow".equals(r.action()))
|
||||||
return true;
|
flag = true;
|
||||||
}
|
return flag;
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private String formatArch(String nati) {
|
private String formatArch(String nati) {
|
||||||
return nati == null ? "" : nati.replace("${arch}", Platform.getPlatform().getBit());
|
return nati == null ? "" : nati.replace("${arch}", Platform.getPlatform().getBit());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNative() {
|
private String getNative() {
|
||||||
switch (OS.os()) {
|
switch (OS.os()) {
|
||||||
case WINDOWS:
|
case WINDOWS:
|
||||||
return formatArch(natives.windows);
|
return formatArch(natives.windows);
|
||||||
case OSX:
|
case OSX:
|
||||||
return formatArch(natives.osx);
|
return formatArch(natives.osx);
|
||||||
default:
|
default:
|
||||||
return formatArch(natives.linux);
|
return formatArch(natives.linux);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRequiredToUnzip() {
|
public boolean isRequiredToUnzip() {
|
||||||
return natives != null && allow();
|
return natives != null && allow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatName() {
|
public String formatName() {
|
||||||
String[] s = name.split(":");
|
String[] s = name.split(":");
|
||||||
if (s.length < 3) {
|
if (s.length < 3)
|
||||||
return null;
|
return null;
|
||||||
}
|
StringBuilder sb = new StringBuilder(s[0].replace('.', '/')).append('/').append(s[1]).append('/').append(s[2]).append('/').append(s[1]).append('-').append(s[2]);
|
||||||
|
if (natives != null)
|
||||||
|
sb.append('-').append(getNative());
|
||||||
|
return sb.append(".jar").toString();
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(s[0].replace('.', '/')).append('/').append(s[1]).append('/').append(s[2]).append('/').append(s[1]).append('-').append(s[2]);
|
@Override
|
||||||
if (natives != null) {
|
public File getFilePath(File gameDir) {
|
||||||
sb.append('-').append(getNative());
|
LibraryDownloadInfo info = getDownloadInfo();
|
||||||
}
|
if (info == null)
|
||||||
|
return null;
|
||||||
|
return new File(gameDir, "libraries/" + info.path);
|
||||||
|
}
|
||||||
|
|
||||||
return sb.append(".jar").toString();
|
@Override
|
||||||
}
|
public Extract getDecompressExtractRules() {
|
||||||
|
return extract == null ? new Extract() : extract;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public LibraryDownloadInfo getDownloadInfo() {
|
||||||
public File getFilePath(File gameDir) {
|
if (downloads == null)
|
||||||
LibraryDownloadInfo info = getDownloadInfo();
|
downloads = new LibrariesDownloadInfo();
|
||||||
if (info == null) {
|
LibraryDownloadInfo info;
|
||||||
return null;
|
if (natives != null) {
|
||||||
}
|
if (downloads.classifiers == null)
|
||||||
return new File(gameDir, "libraries/" + info.path);
|
downloads.classifiers = new HashMap<>();
|
||||||
}
|
if (!downloads.classifiers.containsKey(getNative()))
|
||||||
|
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
||||||
@Override
|
else
|
||||||
public Extract getDecompressExtractRules() {
|
info = downloads.classifiers.get(getNative());
|
||||||
return extract == null ? new Extract() : extract;
|
} else if (downloads.artifact == null)
|
||||||
}
|
downloads.artifact = info = new LibraryDownloadInfo();
|
||||||
|
else
|
||||||
public LibraryDownloadInfo getDownloadInfo() {
|
info = downloads.artifact;
|
||||||
if (downloads == null) {
|
if (StrUtils.isBlank(info.path)) {
|
||||||
downloads = new LibrariesDownloadInfo();
|
info.path = formatName();
|
||||||
}
|
if (info.path == null)
|
||||||
|
return null;
|
||||||
LibraryDownloadInfo info = null;
|
}
|
||||||
if (natives != null) {
|
info.forgeURL = this.url;
|
||||||
if (downloads.classifiers == null) {
|
return info;
|
||||||
downloads.classifiers = new HashMap<>();
|
}
|
||||||
}
|
|
||||||
if (!downloads.classifiers.containsKey(getNative())) {
|
|
||||||
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
|
||||||
} else {
|
|
||||||
info = downloads.classifiers.get(getNative());
|
|
||||||
}
|
|
||||||
} else if (downloads.artifact == null) {
|
|
||||||
downloads.artifact = info = new LibraryDownloadInfo();
|
|
||||||
} else {
|
|
||||||
info = downloads.artifact;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtils.isBlank(info.path)) {
|
|
||||||
info.path = formatName();
|
|
||||||
if (info.path == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.forgeURL = this.url;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -59,158 +59,144 @@ import org.jackhuang.hellominecraft.util.VersionNumber;
|
|||||||
*/
|
*/
|
||||||
public final class Main implements Runnable {
|
public final class Main implements Runnable {
|
||||||
|
|
||||||
private static final X509TrustManager XTM = new X509TrustManager() {
|
private static final X509TrustManager XTM = new X509TrustManager() {
|
||||||
@Override
|
@Override
|
||||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public X509Certificate[] getAcceptedIssuers() {
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
return new X509Certificate[0];
|
return new X509Certificate[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SSLContext sslContext = null;
|
SSLContext sslContext = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sslContext = SSLContext.getInstance("TLS");
|
sslContext = SSLContext.getInstance("TLS");
|
||||||
X509TrustManager[] xtmArray = new X509TrustManager[]{XTM};
|
X509TrustManager[] xtmArray = new X509TrustManager[] { XTM };
|
||||||
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
}
|
}
|
||||||
if (sslContext != null) {
|
if (sslContext != null)
|
||||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||||
}
|
|
||||||
|
|
||||||
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
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 String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@";
|
||||||
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
||||||
|
|
||||||
public static VersionNumber getVersionNumber() {
|
public static VersionNumber getVersionNumber() {
|
||||||
return VersionNumber.check(LAUNCHER_VERSION);
|
return VersionNumber.check(LAUNCHER_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the main window title.
|
* Make the main window title.
|
||||||
*
|
*
|
||||||
* @return the MainWindow title.
|
* @return the MainWindow title.
|
||||||
*/
|
*/
|
||||||
public static String makeTitle() {
|
public static String makeTitle() {
|
||||||
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String shortTitle() {
|
public static String shortTitle() {
|
||||||
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Main INSTANCE = new Main();
|
public static final Main INSTANCE = new Main();
|
||||||
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||||
|
|
||||||
@SuppressWarnings({"CallToPrintStackTrace", "UseSpecificCatch"})
|
@SuppressWarnings({ "CallToPrintStackTrace", "UseSpecificCatch" })
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
PluginManager.getPlugin(DefaultPlugin.class);
|
{
|
||||||
if (IUpgrader.NOW_UPGRADER.parseArguments(getVersionNumber(), args)) {
|
PluginManager.getPlugin(DefaultPlugin.class);
|
||||||
return;
|
if (IUpgrader.NOW_UPGRADER.parseArguments(getVersionNumber(), args))
|
||||||
}
|
return;
|
||||||
|
|
||||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||||
System.setProperty("swing.aatext", "true");
|
System.setProperty("swing.aatext", "true");
|
||||||
System.setProperty("sun.java2d.noddraw", "true");
|
System.setProperty("sun.java2d.noddraw", "true");
|
||||||
System.setProperty("sun.java2d.dpiaware", "false");
|
System.setProperty("sun.java2d.dpiaware", "false");
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File file = new File("hmcl.log");
|
File file = new File("hmcl.log");
|
||||||
if (!file.exists() && !file.createNewFile()) {
|
if (!file.exists() && !file.createNewFile())
|
||||||
HMCLog.warn("Failed to create log file " + file);
|
HMCLog.warn("Failed to create log file " + file);
|
||||||
}
|
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
} catch (IOException ex) {
|
||||||
} catch (IOException ex) {
|
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
||||||
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
||||||
|
|
||||||
String s = Settings.getInstance().getLocalization();
|
String s = Settings.getInstance().getLocalization();
|
||||||
for (SupportedLocales sl : SupportedLocales.values()) {
|
for (SupportedLocales sl : SupportedLocales.values())
|
||||||
if (sl.name().equals(s)) {
|
if (sl.name().equals(s)) {
|
||||||
SupportedLocales.NOW_LOCALE = sl;
|
SupportedLocales.NOW_LOCALE = sl;
|
||||||
Locale.setDefault(sl.self);
|
Locale.setDefault(sl.self);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LogWindow.INSTANCE.clean();
|
LogWindow.INSTANCE.clean();
|
||||||
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
||||||
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
||||||
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
||||||
HMCLog.warn("Failed to set look and feel...", ex);
|
HMCLog.warn("Failed to set look and feel...", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
||||||
Settings.UPDATE_CHECKER.process(false)
|
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
||||||
.reg(t -> Main.invokeUpdate())
|
|
||||||
.regDone(() -> { Settings.UPDATE_CHECKER.checkOutdate(); })
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
||||||
HMCLog.log("Initializing customized proxy");
|
HMCLog.log("Initializing customized proxy");
|
||||||
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
||||||
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
||||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword())) {
|
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword()))
|
||||||
Authenticator.setDefault(new Authenticator() {
|
Authenticator.setDefault(new Authenticator() {
|
||||||
@Override
|
@Override
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PluginManager.plugin().showUI();
|
PluginManager.plugin().showUI();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void invokeUpdate() {
|
public static void invokeUpdate() {
|
||||||
if (Settings.UPDATE_CHECKER.isForceUpdate())
|
MainFrame.INSTANCE.invokeUpdate();
|
||||||
return;
|
}
|
||||||
|
|
||||||
if (Settings.getInstance().ignoreUpdate(
|
public static ImageIcon getIcon(String path) {
|
||||||
Settings.UPDATE_CHECKER.getNewVersion() )) {
|
try {
|
||||||
return;
|
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
HMCLog.err("Failed to load icon", e);
|
||||||
MainFrame.INSTANCE.invokeUpdate();
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public static ImageIcon getIcon(String path) {
|
|
||||||
try {
|
|
||||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
|
||||||
} catch (Exception e) {
|
|
||||||
HMCLog.err("Failed to load icon", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,17 +21,13 @@ import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
|||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||||
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
||||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.VersionNumber;
|
|
||||||
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
||||||
import org.jackhuang.hellominecraft.util.system.OS;
|
import org.jackhuang.hellominecraft.util.system.OS;
|
||||||
|
|
||||||
@@ -69,53 +65,18 @@ public final class Config implements Cloneable {
|
|||||||
private String localization;
|
private String localization;
|
||||||
@SerializedName("logintype")
|
@SerializedName("logintype")
|
||||||
private int logintype;
|
private int logintype;
|
||||||
@SerializedName("downloadSourcetype")
|
@SerializedName("downloadtype")
|
||||||
private int downloadtype;
|
private int downloadtype;
|
||||||
@SerializedName("configurations")
|
@SerializedName("configurations")
|
||||||
private TreeMap<String, Profile> configurations;
|
private TreeMap<String, Profile> configurations;
|
||||||
@SerializedName("auth")
|
@SerializedName("auth")
|
||||||
@SuppressWarnings("FieldMayBeFinal")
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
private Map<String, Map> auth;
|
private Map<String, Map> auth;
|
||||||
@SerializedName("ignoreUpdateVersion")
|
|
||||||
private String ignoreUpdateVersion;
|
|
||||||
@SerializedName("ignoreRecommend")
|
|
||||||
private Set<String> ignoreRecommend;
|
|
||||||
|
|
||||||
public Set<String> getIgnoreRecommend() {
|
|
||||||
if (ignoreRecommend == null) {
|
|
||||||
ignoreRecommend = new HashSet<>();
|
|
||||||
Settings.save();
|
|
||||||
}
|
|
||||||
return ignoreRecommend;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<JdkVersion> getJava() {
|
public List<JdkVersion> getJava() {
|
||||||
return java == null ? java = new ArrayList<>() : java;
|
return java == null ? java = new ArrayList<>() : java;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreUpdate(VersionNumber versionNumber) {
|
|
||||||
boolean ignore = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (StrUtils.isBlank(ignoreUpdateVersion))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
VersionNumber ignoreVersion = VersionNumber.check(ignoreUpdateVersion);
|
|
||||||
if (ignoreVersion == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (versionNumber.compareTo(ignoreVersion) == 0)
|
|
||||||
ignore = true;
|
|
||||||
|
|
||||||
} while(false);
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIgnoreUpdate(VersionNumber versionNumber) {
|
|
||||||
ignoreUpdateVersion = versionNumber.toString();
|
|
||||||
Settings.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public transient final EventHandler<Theme> themeChangedEvent = new EventHandler<>(this);
|
public transient final EventHandler<Theme> themeChangedEvent = new EventHandler<>(this);
|
||||||
public transient final EventHandler<DownloadType> downloadTypeChangedEvent = new EventHandler<>(this);
|
public transient final EventHandler<DownloadType> downloadTypeChangedEvent = new EventHandler<>(this);
|
||||||
public transient final EventHandler<IAuthenticator> authChangedEvent = new EventHandler<>(this);
|
public transient final EventHandler<IAuthenticator> authChangedEvent = new EventHandler<>(this);
|
||||||
@@ -232,8 +193,7 @@ public final class Config implements Cloneable {
|
|||||||
|
|
||||||
public Config() {
|
public Config() {
|
||||||
clientToken = UUID.randomUUID().toString();
|
clientToken = UUID.randomUUID().toString();
|
||||||
logintype = 0;
|
logintype = downloadtype = 0;
|
||||||
downloadtype = DownloadType.Dynamic.ordinal();
|
|
||||||
enableShadow = false;
|
enableShadow = false;
|
||||||
enableAnimation = true;
|
enableAnimation = true;
|
||||||
theme = 4;
|
theme = 4;
|
||||||
@@ -243,7 +203,7 @@ public final class Config implements Cloneable {
|
|||||||
|
|
||||||
public DownloadType getDownloadSource() {
|
public DownloadType getDownloadSource() {
|
||||||
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
||||||
downloadtype = DownloadType.Dynamic.ordinal();
|
downloadtype = 0;
|
||||||
Settings.save();
|
Settings.save();
|
||||||
}
|
}
|
||||||
return DownloadType.values()[downloadtype];
|
return DownloadType.values()[downloadtype];
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
|
|||||||
@@ -17,13 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.launcher.ui;
|
package org.jackhuang.hellominecraft.launcher.ui;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.RowSorter;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
import javax.swing.table.TableRowSorter;
|
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerType;
|
import org.jackhuang.hellominecraft.launcher.core.install.InstallerType;
|
||||||
@@ -40,45 +36,29 @@ import org.jackhuang.hellominecraft.util.ui.SwingUtils;
|
|||||||
*/
|
*/
|
||||||
public class InstallerPanel extends AnimatedPanel {
|
public class InstallerPanel extends AnimatedPanel {
|
||||||
|
|
||||||
GameSettingsPanel gsp;
|
GameSettingsPanel gsp;
|
||||||
|
|
||||||
private static class VerComparator implements Comparator<String> {
|
/**
|
||||||
|
* Creates new form InstallerPanel
|
||||||
|
*
|
||||||
|
* @param gsp To get the minecraft version
|
||||||
|
* @param installerType load which installer
|
||||||
|
*/
|
||||||
|
public InstallerPanel(GameSettingsPanel gsp, InstallerType installerType) {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
@Override
|
setOpaque(false);
|
||||||
public int compare(String o1, String o2) {
|
this.gsp = gsp;
|
||||||
return InstallerVersionList.compareVersion(o1, o2);
|
id = installerType;
|
||||||
}
|
list = Settings.getInstance().getDownloadSource().getProvider().getInstallerByType(id);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form InstallerPanel
|
* 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
|
||||||
* @param gsp To get the minecraft version
|
* regenerated by the Form Editor.
|
||||||
* @param installerType load which installer
|
*/
|
||||||
*/
|
@SuppressWarnings("unchecked")
|
||||||
public InstallerPanel(GameSettingsPanel gsp, InstallerType installerType) {
|
|
||||||
initComponents();
|
|
||||||
|
|
||||||
//表格排序
|
|
||||||
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(lstInstallers.getModel());
|
|
||||||
VerComparator verComparator = new VerComparator();
|
|
||||||
for (int i = 0; i < lstInstallers.getColumnCount(); i++) {
|
|
||||||
sorter.setComparator(i, verComparator);
|
|
||||||
}
|
|
||||||
lstInstallers.setRowSorter(sorter);
|
|
||||||
|
|
||||||
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
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
@@ -129,64 +109,60 @@ public class InstallerPanel extends AnimatedPanel {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void btnInstallActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInstallActionPerformed
|
private void btnInstallActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInstallActionPerformed
|
||||||
downloadSelectedRow();
|
downloadSelectedRow();
|
||||||
}//GEN-LAST:event_btnInstallActionPerformed
|
}//GEN-LAST:event_btnInstallActionPerformed
|
||||||
|
|
||||||
private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
|
private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
|
||||||
refreshVersions();
|
refreshVersions();
|
||||||
}//GEN-LAST:event_btnRefreshActionPerformed
|
}//GEN-LAST:event_btnRefreshActionPerformed
|
||||||
|
|
||||||
transient List<InstallerVersionList.InstallerVersion> versions;
|
transient List<InstallerVersionList.InstallerVersion> versions;
|
||||||
transient InstallerVersionList list;
|
transient InstallerVersionList list;
|
||||||
InstallerType id;
|
InstallerType id;
|
||||||
|
|
||||||
void refreshVersions() {
|
void refreshVersions() {
|
||||||
if (TaskWindow.execute(list.refresh(new String[]{gsp.getMinecraftVersionFormatted()}))) {
|
if (TaskWindow.execute(list.refresh(new String[] { gsp.getMinecraftVersionFormatted() })))
|
||||||
loadVersions();
|
loadVersions();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized InstallerVersionList.InstallerVersion getVersion(int idx) {
|
public synchronized InstallerVersionList.InstallerVersion getVersion(int idx) {
|
||||||
return versions.get(idx);
|
return versions.get(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void downloadSelectedRow() {
|
synchronized void downloadSelectedRow() {
|
||||||
int idx = lstInstallers.getSelectedRow();
|
int idx = lstInstallers.getSelectedRow();
|
||||||
if (versions == null || idx < 0 || idx >= versions.size()) {
|
if (versions == null || idx < 0 || idx >= versions.size()) {
|
||||||
MessageBox.Show(C.i18n("install.not_refreshed"));
|
MessageBox.Show(C.i18n("install.not_refreshed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TaskWindow.execute(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id),
|
TaskWindow.execute(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id),
|
||||||
new TaskRunnable(this::refreshVersions));
|
new TaskRunnable(this::refreshVersions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadVersions() {
|
public void loadVersions() {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
synchronized (InstallerPanel.this) {
|
synchronized (InstallerPanel.this) {
|
||||||
DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel();
|
DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel();
|
||||||
String mcver = StrUtils.formatVersion(gsp.getMinecraftVersionFormatted());
|
String mcver = StrUtils.formatVersion(gsp.getMinecraftVersionFormatted());
|
||||||
versions = list.getVersions(mcver);
|
versions = list.getVersions(mcver);
|
||||||
SwingUtils.clearDefaultTable(lstInstallers);
|
SwingUtils.clearDefaultTable(lstInstallers);
|
||||||
if (versions != null) {
|
if (versions != null)
|
||||||
for (InstallerVersionList.InstallerVersion v : versions) {
|
for (InstallerVersionList.InstallerVersion v : versions)
|
||||||
if (v != null) {
|
if (v != null)
|
||||||
model.addRow(new Object[]{v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion});
|
model.addRow(new Object[] { v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion });
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean refreshed = false;
|
boolean refreshed = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSelect() {
|
public void onSelect() {
|
||||||
if (!refreshed) {
|
if (!refreshed) {
|
||||||
refreshVersions();
|
refreshVersions();
|
||||||
refreshed = true;
|
refreshed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton btnInstall;
|
private javax.swing.JButton btnInstall;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="btnCheckUpdate" min="-2" max="-2" attributes="0"/>
|
<Component id="btnCheckUpdate" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="btnHomepage" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
|
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@@ -127,11 +127,11 @@
|
|||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="btnCheckUpdate" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
<Component id="btnCheckUpdate" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||||
<Component id="chkDecorated" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="chkDecorated" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnHomepage" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="lblRestart" min="-2" max="-2" attributes="0"/>
|
<Component id="lblRestart" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="116" max="32767" attributes="0"/>
|
<EmptySpace pref="65" max="32767" attributes="0"/>
|
||||||
<Component id="lblModpack" min="-2" max="-2" attributes="0"/>
|
<Component id="lblModpack" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="lblAbout" min="-2" max="-2" attributes="0"/>
|
<Component id="lblAbout" min="-2" max="-2" attributes="0"/>
|
||||||
@@ -157,9 +157,12 @@
|
|||||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="launcher.about" replaceFormat="C.i18n("{key}")"/>
|
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="launcher.about" replaceFormat="C.i18n("{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
|
||||||
<Color id="默认光标"/>
|
<Color id="手型光标"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="lblAboutMouseClicked"/>
|
||||||
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="btnSelBackgroundPath">
|
<Component class="javax.swing.JButton" name="btnSelBackgroundPath">
|
||||||
<Properties>
|
<Properties>
|
||||||
@@ -345,15 +348,13 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="btnHomepage">
|
<Component class="javax.swing.JButton" name="btnMCBBS">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" value="MCBBS"/>
|
||||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="launcher.homepage" replaceFormat="C.i18n("{key}")"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnHomepageActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
|
||||||
</Events>
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
cboLang = new javax.swing.JComboBox();
|
cboLang = new javax.swing.JComboBox();
|
||||||
lblLang = new javax.swing.JLabel();
|
lblLang = new javax.swing.JLabel();
|
||||||
lblRestart = new javax.swing.JLabel();
|
lblRestart = new javax.swing.JLabel();
|
||||||
btnHomepage = new javax.swing.JButton();
|
btnMCBBS = new javax.swing.JButton();
|
||||||
|
|
||||||
cboDownloadSource.addItemListener(new java.awt.event.ItemListener() {
|
cboDownloadSource.addItemListener(new java.awt.event.ItemListener() {
|
||||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||||
@@ -125,7 +125,12 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
lblAbout.setText(C.i18n("launcher.about")); // NOI18N
|
lblAbout.setText(C.i18n("launcher.about")); // NOI18N
|
||||||
lblAbout.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
|
lblAbout.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
|
||||||
|
lblAbout.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||||
|
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||||
|
lblAboutMouseClicked(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
btnSelBackgroundPath.setText(C.i18n("ui.button.explore")); // NOI18N
|
btnSelBackgroundPath.setText(C.i18n("ui.button.explore")); // NOI18N
|
||||||
btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() {
|
btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() {
|
||||||
@@ -236,11 +241,11 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
|
|
||||||
lblRestart.setText(C.i18n("launcher.restart")); // NOI18N
|
lblRestart.setText(C.i18n("launcher.restart")); // NOI18N
|
||||||
|
|
||||||
btnHomepage.setText(C.i18n("launcher.homepage")); // NOI18N
|
btnMCBBS.setText("MCBBS");
|
||||||
btnHomepage.setToolTipText("");
|
btnMCBBS.setToolTipText("");
|
||||||
btnHomepage.addActionListener(new java.awt.event.ActionListener() {
|
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
btnHomepageActionPerformed(evt);
|
btnMCBBSActionPerformed(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -258,7 +263,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(btnCheckUpdate)
|
.addComponent(btnCheckUpdate)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(btnHomepage)
|
.addComponent(btnMCBBS)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(chkDecorated))
|
.addComponent(chkDecorated))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@@ -341,10 +346,10 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(chkDecorated)
|
.addComponent(chkDecorated)
|
||||||
.addComponent(btnHomepage))
|
.addComponent(btnMCBBS))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(lblRestart)
|
.addComponent(lblRestart)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 116, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 65, Short.MAX_VALUE)
|
||||||
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
@@ -384,9 +389,8 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
}//GEN-LAST:event_txtBackgroundPathFocusLost
|
}//GEN-LAST:event_txtBackgroundPathFocusLost
|
||||||
|
|
||||||
private void btnCheckUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckUpdateActionPerformed
|
private void btnCheckUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckUpdateActionPerformed
|
||||||
Settings.UPDATE_CHECKER.process(true)
|
Settings.UPDATE_CHECKER.process(true);
|
||||||
.regDone(() -> { Settings.UPDATE_CHECKER.checkOutdate(); })
|
Settings.UPDATE_CHECKER.checkOutdate();
|
||||||
.execute();
|
|
||||||
}//GEN-LAST:event_btnCheckUpdateActionPerformed
|
}//GEN-LAST:event_btnCheckUpdateActionPerformed
|
||||||
|
|
||||||
private void cboThemeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboThemeItemStateChanged
|
private void cboThemeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboThemeItemStateChanged
|
||||||
@@ -394,7 +398,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
}//GEN-LAST:event_cboThemeItemStateChanged
|
}//GEN-LAST:event_cboThemeItemStateChanged
|
||||||
|
|
||||||
private void lblModpackMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModpackMouseClicked
|
private void lblModpackMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModpackMouseClicked
|
||||||
SwingUtils.openLink("http://client.api.mcgogogo.com:81/link.php?type=modpack");
|
SwingUtils.openLink("http://huangyuhui.duapp.com/link.php?type=modpack");
|
||||||
}//GEN-LAST:event_lblModpackMouseClicked
|
}//GEN-LAST:event_lblModpackMouseClicked
|
||||||
|
|
||||||
private void cboLangItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLangItemStateChanged
|
private void cboLangItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLangItemStateChanged
|
||||||
@@ -429,13 +433,17 @@ public class LauncherSettingsPanel extends AnimatedPanel {
|
|||||||
Settings.getInstance().setProxyPassword(txtProxyPassword.getText());
|
Settings.getInstance().setProxyPassword(txtProxyPassword.getText());
|
||||||
}//GEN-LAST:event_txtProxyPasswordFocusLost
|
}//GEN-LAST:event_txtProxyPasswordFocusLost
|
||||||
|
|
||||||
private void btnHomepageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnHomepageActionPerformed
|
private void lblAboutMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblAboutMouseClicked
|
||||||
|
SwingUtils.openLink("http://huangyuhui.duapp.com/link.php?type=sponsor");
|
||||||
|
}//GEN-LAST:event_lblAboutMouseClicked
|
||||||
|
|
||||||
|
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
|
||||||
SwingUtils.openLink(C.URL_PUBLISH);
|
SwingUtils.openLink(C.URL_PUBLISH);
|
||||||
}//GEN-LAST:event_btnHomepageActionPerformed
|
}//GEN-LAST:event_btnMCBBSActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton btnCheckUpdate;
|
private javax.swing.JButton btnCheckUpdate;
|
||||||
private javax.swing.JButton btnHomepage;
|
private javax.swing.JButton btnMCBBS;
|
||||||
private javax.swing.JButton btnSelBackgroundPath;
|
private javax.swing.JButton btnSelBackgroundPath;
|
||||||
private javax.swing.JComboBox cboDownloadSource;
|
private javax.swing.JComboBox cboDownloadSource;
|
||||||
private javax.swing.JComboBox cboLang;
|
private javax.swing.JComboBox cboLang;
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
|||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.DynamicDownloadProvider;
|
|
||||||
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
||||||
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
||||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||||
@@ -86,27 +85,23 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
setUndecorated(!Settings.getInstance().isDecorated());
|
setUndecorated(!Settings.getInstance().isDecorated());
|
||||||
defaultTitle = isUndecorated() ? Main.makeTitle() : "";
|
defaultTitle = isUndecorated() ? Main.makeTitle() : "";
|
||||||
enableShadow = Settings.getInstance().isEnableShadow() && isUndecorated();
|
enableShadow = Settings.getInstance().isEnableShadow() && isUndecorated();
|
||||||
if (enableShadow) {
|
if (enableShadow)
|
||||||
setContentSize(834, 542);
|
setContentSize(834, 542);
|
||||||
} else {
|
else
|
||||||
setContentSize(802, 511);
|
setContentSize(802, 511);
|
||||||
}
|
setDefaultCloseOperation(3);
|
||||||
|
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
||||||
setTitle(Main.makeTitle());
|
setTitle(Main.makeTitle());
|
||||||
initComponents();
|
initComponents();
|
||||||
loadBackground();
|
loadBackground();
|
||||||
|
|
||||||
DynamicDownloadProvider.getInstance().init();
|
|
||||||
|
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
if (MainFrame.this.isUndecorated()) {
|
if (MainFrame.this.isUndecorated())
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
}
|
|
||||||
|
|
||||||
this.addWindowListener(new WindowListener() {
|
this.addWindowListener(new WindowListener() {
|
||||||
@Override
|
@Override
|
||||||
public void windowOpened(WindowEvent e) { }
|
public void windowOpened(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent e) {
|
public void windowClosing(WindowEvent e) {
|
||||||
@@ -114,13 +109,16 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowClosed(WindowEvent e) { }
|
public void windowClosed(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowIconified(WindowEvent e) { }
|
public void windowIconified(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeiconified(WindowEvent e) { }
|
public void windowDeiconified(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowActivated(WindowEvent e) {
|
public void windowActivated(WindowEvent e) {
|
||||||
@@ -133,10 +131,11 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeactivated(WindowEvent e) { }
|
public void windowDeactivated(WindowEvent e) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (enableShadow) {
|
if (enableShadow)
|
||||||
try {
|
try {
|
||||||
setBackground(new Color(0, 0, 0, 0));
|
setBackground(new Color(0, 0, 0, 0));
|
||||||
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
||||||
@@ -145,8 +144,6 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
Settings.getInstance().setEnableShadow(false);
|
Settings.getInstance().setEnableShadow(false);
|
||||||
setSize(802, 511);
|
setSize(802, 511);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
((JPanel) getContentPane()).setOpaque(true);
|
((JPanel) getContentPane()).setOpaque(true);
|
||||||
|
|
||||||
Settings.getInstance().themeChangedEvent.register(this::reloadColor);
|
Settings.getInstance().themeChangedEvent.register(this::reloadColor);
|
||||||
|
|||||||
@@ -277,16 +277,5 @@
|
|||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JPanel" name="contentPanel">
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
|
||||||
<AbsoluteConstraints x="220" y="40" width="540" height="320"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
|
||||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -85,9 +85,6 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
|
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
|
||||||
pnlMore.setOpaque(true);
|
pnlMore.setOpaque(true);
|
||||||
|
|
||||||
recommendPanel = new RecommendPanel();
|
|
||||||
contentPanel.add(recommendPanel);
|
|
||||||
|
|
||||||
Settings.getInstance().authChangedEvent.register(onAuthChanged);
|
Settings.getInstance().authChangedEvent.register(onAuthChanged);
|
||||||
Settings.profileLoadingEvent.register(onLoadingProfiles);
|
Settings.profileLoadingEvent.register(onLoadingProfiles);
|
||||||
Settings.profileChangedEvent.register(onSelectedProfilesChanged);
|
Settings.profileChangedEvent.register(onSelectedProfilesChanged);
|
||||||
@@ -125,7 +122,6 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
btnLogout = new javax.swing.JButton();
|
btnLogout = new javax.swing.JButton();
|
||||||
btnImportModpack = new javax.swing.JButton();
|
btnImportModpack = new javax.swing.JButton();
|
||||||
btnExportModpack = new javax.swing.JButton();
|
btnExportModpack = new javax.swing.JButton();
|
||||||
contentPanel = new javax.swing.JPanel();
|
|
||||||
|
|
||||||
setLayout(null);
|
setLayout(null);
|
||||||
|
|
||||||
@@ -266,7 +262,7 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
.addComponent(lblVersion, javax.swing.GroupLayout.Alignment.TRAILING))
|
.addComponent(lblVersion, javax.swing.GroupLayout.Alignment.TRAILING))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(cboProfiles, 0, 128, Short.MAX_VALUE)
|
||||||
.addComponent(cboVersions, 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.createSequentialGroup()
|
||||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@@ -310,10 +306,6 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
|
|
||||||
add(pnlMore);
|
add(pnlMore);
|
||||||
pnlMore.setBounds(0, 0, 190, 480);
|
pnlMore.setBounds(0, 0, 190, 480);
|
||||||
|
|
||||||
contentPanel.setLayout(null);
|
|
||||||
add(contentPanel);
|
|
||||||
contentPanel.setBounds(220, 40, 540, 320);
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void txtPlayerNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusGained
|
private void txtPlayerNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusGained
|
||||||
@@ -435,8 +427,6 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
Settings.onProfileLoading();
|
Settings.onProfileLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecommendPanel recommendPanel;
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton btnExportModpack;
|
private javax.swing.JButton btnExportModpack;
|
||||||
private javax.swing.JButton btnImportModpack;
|
private javax.swing.JButton btnImportModpack;
|
||||||
@@ -444,7 +434,6 @@ public class MainPagePanel extends AnimatedPanel {
|
|||||||
private javax.swing.JComboBox cboLoginMode;
|
private javax.swing.JComboBox cboLoginMode;
|
||||||
private javax.swing.JComboBox cboProfiles;
|
private javax.swing.JComboBox cboProfiles;
|
||||||
private javax.swing.JComboBox cboVersions;
|
private javax.swing.JComboBox cboVersions;
|
||||||
private javax.swing.JPanel contentPanel;
|
|
||||||
private javax.swing.JLabel jLabel10;
|
private javax.swing.JLabel jLabel10;
|
||||||
private javax.swing.JLabel jLabel7;
|
private javax.swing.JLabel jLabel7;
|
||||||
private javax.swing.JLabel jLabel9;
|
private javax.swing.JLabel jLabel9;
|
||||||
|
|||||||
@@ -1,338 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 evilwk <evilwk@gmail.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.hellominecraft.launcher.ui;
|
|
||||||
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Image;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.SwingWorker;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import java.awt.Cursor;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
|
||||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
|
||||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author evilwk <evilwk@gmail.com>
|
|
||||||
*/
|
|
||||||
public class RecommendPanel extends JPanel {
|
|
||||||
|
|
||||||
private static final int SWITCH_INTERVAL = 10;
|
|
||||||
|
|
||||||
private static final int SPACE = 10;
|
|
||||||
private static final int TOP_POSITION = 2;
|
|
||||||
|
|
||||||
private JButton closeButton;
|
|
||||||
|
|
||||||
private Image currImage;
|
|
||||||
private String imageKey = null;
|
|
||||||
private boolean ignoreSwitch = false;
|
|
||||||
private List<RecommendInfo> recommends;
|
|
||||||
|
|
||||||
public final ScheduledExecutorService scheduledexec = Executors.newScheduledThreadPool(1);
|
|
||||||
|
|
||||||
public RecommendPanel() {
|
|
||||||
initComponents();
|
|
||||||
|
|
||||||
recommends = new ArrayList<RecommendInfo>();
|
|
||||||
new LoadImages().execute();
|
|
||||||
setCursor(new Cursor(Cursor.HAND_CURSOR));
|
|
||||||
|
|
||||||
addMouseListener(new MouseAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
MouseClicked(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
this.setLayout(null);
|
|
||||||
|
|
||||||
closeButton = new JButton(Main.getIcon("re_close.png"));
|
|
||||||
closeButton.setRolloverIcon(Main.getIcon("re_close_enter.png"));
|
|
||||||
closeButton.setBorder(BorderFactory.createEmptyBorder());
|
|
||||||
closeButton.setContentAreaFilled(false);
|
|
||||||
closeButton.addActionListener((e) -> ignoreTheRecommend(imageKey));
|
|
||||||
closeButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
|
||||||
closeButton.setFocusable(false);
|
|
||||||
closeButton.setBounds(0, 0, 12, 12);
|
|
||||||
closeButton.setVisible(false);
|
|
||||||
this.add(closeButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ignoreTheRecommend(String url) {
|
|
||||||
synchronized(RecommendPanel.class) {
|
|
||||||
if (StrUtils.isNotBlank(url)) {
|
|
||||||
Settings.getInstance().getIgnoreRecommend().add(url);
|
|
||||||
Settings.save();
|
|
||||||
|
|
||||||
ignoreSwitch = true;
|
|
||||||
showNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MouseClicked(MouseEvent evt) {
|
|
||||||
if (imageKey == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RecommendInfo info = recommends.get(getCurrentImageIndex());
|
|
||||||
if (StrUtils.isNotBlank(info.link)) {
|
|
||||||
if (info.once) {
|
|
||||||
ignoreTheRecommend(info.url);
|
|
||||||
}
|
|
||||||
SwingUtils.openLink(info.link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showImages() {
|
|
||||||
if (recommends.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (RecommendInfo info : recommends) {
|
|
||||||
if (!ignoreShowUrl(info.url)) {
|
|
||||||
try {
|
|
||||||
File tempFile = File.createTempFile("hmcl", "png");
|
|
||||||
String tempPath = tempFile.getCanonicalPath();
|
|
||||||
if (NetUtils.download(info.url, tempPath)) {
|
|
||||||
info.image = ImageIO.read(tempFile);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getImagesSize() == 0 || showIfOnly()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scheduledexec.scheduleAtFixedRate(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
synchronized(RecommendPanel.class) {
|
|
||||||
if (ignoreSwitch) {
|
|
||||||
ignoreSwitch = false;
|
|
||||||
} else {
|
|
||||||
showNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 0, SWITCH_INTERVAL, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getImagesSize() {
|
|
||||||
int imageCount = 0;
|
|
||||||
for (RecommendInfo recommend : recommends) {
|
|
||||||
if (recommend.image != null) {
|
|
||||||
imageCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return imageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean showIfOnly() {
|
|
||||||
if (getImagesSize() != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (RecommendInfo recommend : recommends) {
|
|
||||||
if (recommend.image != null) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
RecommendPanel.this.setImage(recommend.url, recommend.image);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showNext() {
|
|
||||||
if (getCanShowImageCount() == 0) {
|
|
||||||
setVisible(false);
|
|
||||||
scheduledexec.shutdown();
|
|
||||||
} else {
|
|
||||||
int showIndex = getNextImageIndex();
|
|
||||||
RecommendInfo info = recommends.get(showIndex);
|
|
||||||
setImage(info.url, info.image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean ignoreShowUrl(String url) {
|
|
||||||
if (StrUtils.isBlank(url)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return Settings.getInstance().getIgnoreRecommend().contains(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCanShowImageCount() {
|
|
||||||
int imageCount = 0;
|
|
||||||
for (RecommendInfo recommend : recommends) {
|
|
||||||
if (recommend.image != null && !ignoreShowUrl(recommend.url)) {
|
|
||||||
imageCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return imageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNextImageIndex(int showIndex) {
|
|
||||||
if (showIndex >= recommends.size()) {
|
|
||||||
showIndex = 0;
|
|
||||||
}
|
|
||||||
RecommendInfo info = recommends.get(showIndex);
|
|
||||||
if (info.image == null || ignoreShowUrl(info.url)) {
|
|
||||||
showIndex = getNextImageIndex(++showIndex);
|
|
||||||
}
|
|
||||||
return showIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNextImageIndex() {
|
|
||||||
int showIndex = getCurrentImageIndex();
|
|
||||||
if (++showIndex >= recommends.size()) {
|
|
||||||
showIndex = 0;
|
|
||||||
}
|
|
||||||
showIndex = getNextImageIndex(showIndex);
|
|
||||||
return showIndex >= recommends.size() ? 0 : showIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentImageIndex() {
|
|
||||||
int currIndex = 0;
|
|
||||||
for (int i = 0; i < recommends.size(); i++) {
|
|
||||||
RecommendInfo info = recommends.get(i);
|
|
||||||
if (StrUtils.isNotBlank(imageKey) && info.url.equals(imageKey)) {
|
|
||||||
currIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImage(String key, Image image) {
|
|
||||||
this.imageKey = key;
|
|
||||||
this.currImage = image;
|
|
||||||
|
|
||||||
int btnWidth = closeButton.getWidth();
|
|
||||||
|
|
||||||
setSize(image.getWidth(this) + SPACE + btnWidth, image.getHeight(this));
|
|
||||||
closeButton.setLocation(getWidth() - btnWidth, TOP_POSITION);
|
|
||||||
closeButton.setVisible(true);
|
|
||||||
|
|
||||||
SwingUtilities.updateComponentTreeUI(this.getRootPane());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
if (currImage != null) {
|
|
||||||
g.drawImage(currImage, 0, 0, currImage.getWidth(this), currImage.getHeight(this), this);
|
|
||||||
}
|
|
||||||
super.paintComponent(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
static class RecommendInfo {
|
|
||||||
String url;
|
|
||||||
String link;
|
|
||||||
boolean once;
|
|
||||||
Image image;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadImages extends SwingWorker<List<Map<String, Object>>, Void> {
|
|
||||||
|
|
||||||
private static final String RECOMMEND_URL = "http://client.api.mcgogogo.com:81/recommend.php";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<Map<String, Object>> doInBackground() throws Exception {
|
|
||||||
List<Map<String, Object>> infos = null;
|
|
||||||
do {
|
|
||||||
String content = NetUtils.get(RECOMMEND_URL);
|
|
||||||
if (content == null || content.equals("")) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Object> data = new Gson().fromJson(content,
|
|
||||||
new TypeToken<Map<String, Object>>() {}.getType());
|
|
||||||
if (data == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
infos = (List<Map<String, Object>>) data.get("data");
|
|
||||||
} while (false);
|
|
||||||
return infos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void done() {
|
|
||||||
try {
|
|
||||||
List<Map<String, Object>> infos = this.get();
|
|
||||||
if (infos == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Map<String, Object> info : infos) {
|
|
||||||
RecommendInfo recommend = new RecommendInfo();
|
|
||||||
if (info.get("url") != null) {
|
|
||||||
recommend.url = (String) info.get("url");
|
|
||||||
} else {
|
|
||||||
recommend.url = "";
|
|
||||||
}
|
|
||||||
if (info.get("link") != null) {
|
|
||||||
recommend.link = (String) info.get("link");
|
|
||||||
} else {
|
|
||||||
recommend.link = "";
|
|
||||||
}
|
|
||||||
if (info.get("once") != null) {
|
|
||||||
recommend.once = (boolean) info.get("once");
|
|
||||||
} else {
|
|
||||||
recommend.once = false;
|
|
||||||
}
|
|
||||||
recommend.image = null;
|
|
||||||
recommends.add(recommend);
|
|
||||||
}
|
|
||||||
RecommendPanel.this.showImages();
|
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -138,9 +138,9 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
|||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
map.put("CrashReport", text);
|
map.put("CrashReport", text);
|
||||||
try {
|
try {
|
||||||
NetUtils.post(NetUtils.constantURL("http://client.api.mcgogogo.com:81/crash_report.php"), map);
|
NetUtils.post(NetUtils.constantURL("http://huangyuhui.duapp.com/crash.php"), map);
|
||||||
} catch (Throwable error) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to post HMCL server.", error);
|
LOGGER.log(Level.SEVERE, "Failed to post HMCL server.", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.launcher.util.upgrade;
|
package org.jackhuang.hellominecraft.launcher.util.upgrade;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@@ -37,30 +36,20 @@ import java.util.jar.JarFile;
|
|||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
import java.util.jar.Pack200;
|
import java.util.jar.Pack200;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JCheckBox;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTextPane;
|
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
|
||||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||||
|
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||||
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
|
||||||
import org.jackhuang.hellominecraft.util.UpdateChecker;
|
import org.jackhuang.hellominecraft.util.UpdateChecker;
|
||||||
import org.jackhuang.hellominecraft.util.Utils;
|
import org.jackhuang.hellominecraft.util.Utils;
|
||||||
import org.jackhuang.hellominecraft.util.VersionNumber;
|
import org.jackhuang.hellominecraft.util.VersionNumber;
|
||||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
|
||||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||||
import org.jackhuang.hellominecraft.util.system.OS;
|
import org.jackhuang.hellominecraft.util.system.OS;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.TaskList;
|
|
||||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -109,96 +98,42 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean askUpdateVersion(VersionNumber versionNumber) {
|
|
||||||
if (!Settings.UPDATE_CHECKER.isManualUpdate() &&
|
|
||||||
Settings.getInstance().ignoreUpdate(versionNumber))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
String content = C.i18n("update.newest_version") +
|
|
||||||
versionNumber.firstVer + "." + versionNumber.secondVer + "." +
|
|
||||||
versionNumber.thirdVer + "\n" +
|
|
||||||
C.i18n("update.should_open_link");
|
|
||||||
|
|
||||||
JCheckBox checkbox = new JCheckBox(C.i18n("update.ignore"));
|
|
||||||
|
|
||||||
JPanel logPanel = new JPanel();
|
|
||||||
logPanel.setLayout(new BoxLayout(logPanel, BoxLayout.X_AXIS));
|
|
||||||
logPanel.setPreferredSize(new Dimension(300,150));
|
|
||||||
logPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 5));
|
|
||||||
|
|
||||||
JScrollPane scrollPane = new JScrollPane();
|
|
||||||
JTextPane textPane = new JTextPane();
|
|
||||||
textPane.setContentType("text/plain");
|
|
||||||
textPane.setEditable(false);
|
|
||||||
|
|
||||||
scrollPane.setViewportView(textPane);
|
|
||||||
logPanel.add(scrollPane);
|
|
||||||
|
|
||||||
int msgRet;
|
|
||||||
String updateLog = Settings.UPDATE_CHECKER.getUpdateLog();
|
|
||||||
if (StrUtils.isBlank(updateLog)) {
|
|
||||||
msgRet = MessageBox.Show(new Object[]{content, checkbox}, MessageBox.YES_NO_OPTION);
|
|
||||||
} else {
|
|
||||||
textPane.setText(updateLog);
|
|
||||||
msgRet = MessageBox.Show(new Object[]{content, logPanel, checkbox}, MessageBox.YES_NO_OPTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msgRet == MessageBox.NO_OPTION) {
|
|
||||||
if (checkbox.isSelected()) {
|
|
||||||
Settings.getInstance().setIgnoreUpdate(versionNumber);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean call(Object sender, final VersionNumber number) {
|
public boolean call(Object sender, final VersionNumber number) {
|
||||||
((UpdateChecker) sender).requestDownloadLink().reg(new Consumer<Map<String, String>>() {
|
((UpdateChecker) sender).requestDownloadLink().reg(map -> {
|
||||||
@Override
|
if (MessageBox.Show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.thirdVer + "\n"
|
||||||
public void accept(Map<String, String> map) {
|
+ C.i18n("update.should_open_link"),
|
||||||
boolean isForceUpdate = Settings.UPDATE_CHECKER.isForceUpdate();
|
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||||
if (isForceUpdate || askUpdateVersion(number))
|
if (map != null && map.containsKey("pack"))
|
||||||
if (map != null && map.containsKey("pack"))
|
try {
|
||||||
try {
|
String hash = null;
|
||||||
String hash = null;
|
if (map.containsKey("packsha1"))
|
||||||
if (map.containsKey("packsha1")) {
|
hash = map.get("packsha1");
|
||||||
hash = map.get("packsha1");
|
if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version, hash)).create()) {
|
||||||
}
|
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start();
|
||||||
AppDataUpgraderTask upgraderTask = new AppDataUpgraderTask(map.get("pack"), number.version, hash);
|
System.exit(0);
|
||||||
if (isForceUpdate) {
|
}
|
||||||
TaskList tasks = new TaskList();
|
} catch (IOException ex) {
|
||||||
tasks.addTask(upgraderTask);
|
HMCLog.err("Failed to create upgrader", ex);
|
||||||
tasks.start();
|
}
|
||||||
} else {
|
else {
|
||||||
if (TaskWindow.factory().append(upgraderTask).create()) {
|
String url = C.URL_PUBLISH;
|
||||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start();
|
if (map != null)
|
||||||
System.exit(0);
|
if (map.containsKey(OS.os().checked_name))
|
||||||
}
|
url = map.get(OS.os().checked_name);
|
||||||
}
|
else if (map.containsKey(OS.UNKOWN.checked_name))
|
||||||
} catch (IOException ex) {
|
url = map.get(OS.UNKOWN.checked_name);
|
||||||
HMCLog.err("Failed to create upgrader", ex);
|
if (url == null)
|
||||||
}
|
url = C.URL_PUBLISH;
|
||||||
else {
|
try {
|
||||||
String url = C.URL_PUBLISH;
|
java.awt.Desktop.getDesktop().browse(new URI(url));
|
||||||
if (map != null)
|
} catch (URISyntaxException | IOException e) {
|
||||||
if (map.containsKey(OS.os().checked_name))
|
HMCLog.warn("Failed to browse uri: " + url, e);
|
||||||
url = map.get(OS.os().checked_name);
|
Utils.setClipborad(url);
|
||||||
else if (map.containsKey(OS.UNKOWN.checked_name))
|
MessageBox.Show(C.i18n("update.no_browser"));
|
||||||
url = map.get(OS.UNKOWN.checked_name);
|
}
|
||||||
if (url == null)
|
}
|
||||||
url = C.URL_PUBLISH;
|
}).execute();
|
||||||
try {
|
|
||||||
java.awt.Desktop.getDesktop().browse(new URI(url));
|
|
||||||
} catch (URISyntaxException | IOException e) {
|
|
||||||
HMCLog.warn("Failed to browse uri: " + url, e);
|
|
||||||
Utils.setClipborad(url);
|
|
||||||
MessageBox.Show(C.i18n("update.no_browser"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).execute();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -29,10 +29,10 @@ public final class C {
|
|||||||
|
|
||||||
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
public static final String URL_PUBLISH = "http://www.hmclsoft.com";
|
//http://repo1.maven.org/maven2
|
||||||
public static final String URL_GITHUB = "https://github.com/mclauncher/HMCL/issues";
|
public static final String URL_PUBLISH = "http://www.mcbbs.net/thread-142335-1-1.html";
|
||||||
|
|
||||||
public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher";
|
public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher";
|
||||||
|
public static final String URL_GITHUB = "https://github.com/huanghongxun/HMCL/issues";
|
||||||
public static final String URL_MINECRAFTFORUM = "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265720-hello-minecraft-launcher-1-9-3-mc-1-7-4-auto";
|
public static final String URL_MINECRAFTFORUM = "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265720-hello-minecraft-launcher-1-9-3-mc-1-7-4-auto";
|
||||||
|
|
||||||
public static final String FILE_MINECRAFT_VERSIONS = "versions";
|
public static final String FILE_MINECRAFT_VERSIONS = "versions";
|
||||||
|
|||||||
@@ -26,28 +26,10 @@ import java.util.Map;
|
|||||||
public interface IUpdateChecker {
|
public interface IUpdateChecker {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update response
|
*
|
||||||
*/
|
*/
|
||||||
void checkOutdate();
|
void checkOutdate();
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return Update log
|
|
||||||
*/
|
|
||||||
String getUpdateLog();
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return Server to assign a mandatory update
|
|
||||||
*/
|
|
||||||
boolean isForceUpdate();
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return User manual update
|
|
||||||
*/
|
|
||||||
boolean isManualUpdate();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the <b>cached</b> newest version number, use "process" method to
|
* Get the <b>cached</b> newest version number, use "process" method to
|
||||||
* download!
|
* download!
|
||||||
|
|||||||
@@ -86,23 +86,23 @@ public class MessageBox {
|
|||||||
/**
|
/**
|
||||||
* Show MsgBox with title and options
|
* Show MsgBox with title and options
|
||||||
*
|
*
|
||||||
* @param msg The Message
|
* @param Msg The Message
|
||||||
* @param title The title of MsgBox.
|
* @param Title The title of MsgBox.
|
||||||
* @param optionType The type of MsgBox.
|
* @param Option The type of MsgBox.
|
||||||
*
|
*
|
||||||
* @return user operation.
|
* @return user operation.
|
||||||
*/
|
*/
|
||||||
public static int Show(Object msg, String title, int optionType) {
|
public static int Show(String Msg, String Title, int Option) {
|
||||||
switch (optionType) {
|
switch (Option) {
|
||||||
case YES_NO_OPTION:
|
case YES_NO_OPTION:
|
||||||
case YES_NO_CANCEL_OPTION:
|
case YES_NO_CANCEL_OPTION:
|
||||||
case OK_CANCEL_OPTION:
|
case OK_CANCEL_OPTION:
|
||||||
return SwingUtils.invokeAndWait(() -> JOptionPane.showConfirmDialog(null, msg, title, optionType - 10));
|
return SwingUtils.invokeAndWait(() -> JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10));
|
||||||
default:
|
default:
|
||||||
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, msg, title, optionType));
|
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, Msg, Title, Option));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show MsgBox with options
|
* Show MsgBox with options
|
||||||
@@ -112,8 +112,8 @@ public class MessageBox {
|
|||||||
*
|
*
|
||||||
* @return User Operation
|
* @return User Operation
|
||||||
*/
|
*/
|
||||||
public static int Show(Object msg, int optionType) {
|
public static int Show(String Msg, int Option) {
|
||||||
return Show(msg, TITLE, optionType);
|
return Show(Msg, TITLE, Option);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,8 +123,8 @@ public class MessageBox {
|
|||||||
*
|
*
|
||||||
* @return User Operation
|
* @return User Operation
|
||||||
*/
|
*/
|
||||||
public static int Show(Object msg) {
|
public static int Show(String Msg) {
|
||||||
return Show(msg, TITLE, INFORMATION_MESSAGE);
|
return Show(Msg, TITLE, INFORMATION_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ShowLocalized(String msg) {
|
public static int ShowLocalized(String msg) {
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ package org.jackhuang.hellominecraft.util;
|
|||||||
|
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -132,23 +130,6 @@ public final class NetUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean download(String url, String saveFile) {
|
|
||||||
try {
|
|
||||||
int readCount = 0;
|
|
||||||
byte[] buffer = new byte[1204];
|
|
||||||
InputStream inputStream = new URL(url).openConnection().getInputStream();
|
|
||||||
FileOutputStream fs = new FileOutputStream(saveFile);
|
|
||||||
while ((readCount = inputStream.read(buffer)) != -1) {
|
|
||||||
fs.write(buffer, 0, readCount);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
return false;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String DEFAULT_CHARSET = "UTF-8";
|
private static final String DEFAULT_CHARSET = "UTF-8";
|
||||||
|
|
||||||
public static URL constantURL(String url) {
|
public static URL constantURL(String url) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jackhuang.hellominecraft.util;
|
|||||||
|
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -27,20 +26,9 @@ import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
|||||||
*/
|
*/
|
||||||
public final class UpdateChecker implements IUpdateChecker {
|
public final class UpdateChecker implements IUpdateChecker {
|
||||||
|
|
||||||
public static final String VERSION_URL = "http://client.api.mcgogogo.com:81/version.php?type=";
|
|
||||||
public static final String UPDATE_LINK_URL = "http://client.api.mcgogogo.com:81/update_link.php?type=";
|
|
||||||
|
|
||||||
public boolean OUT_DATED = false;
|
public boolean OUT_DATED = false;
|
||||||
|
|
||||||
public String versionString;
|
|
||||||
public VersionNumber base;
|
public VersionNumber base;
|
||||||
private VersionNumber value;
|
public String versionString;
|
||||||
|
|
||||||
private boolean isforceUpdate = false;
|
|
||||||
private boolean isManualUpdate = false;
|
|
||||||
|
|
||||||
private String updateLog = null;
|
|
||||||
|
|
||||||
public String type;
|
public String type;
|
||||||
private Map<String, String> download_link = null;
|
private Map<String, String> download_link = null;
|
||||||
|
|
||||||
@@ -49,39 +37,26 @@ public final class UpdateChecker implements IUpdateChecker {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VersionNumber value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OverridableSwingWorker<VersionNumber> process(final boolean showMessage) {
|
public OverridableSwingWorker<VersionNumber> process(final boolean showMessage) {
|
||||||
return new OverridableSwingWorker() {
|
return new OverridableSwingWorker() {
|
||||||
@Override
|
@Override
|
||||||
protected void work() throws Exception {
|
protected void work() throws Exception {
|
||||||
isManualUpdate = showMessage;
|
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
versionString = NetUtils.get(VERSION_URL + type +
|
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||||
"&ver=" + base.toString() +
|
value = VersionNumber.check(versionString);
|
||||||
"&lang=" + SupportedLocales.NOW_LOCALE.self);
|
|
||||||
|
|
||||||
Map<String, Object> versionInfo = C.GSON.fromJson(versionString, Map.class);
|
|
||||||
if (versionInfo.containsKey("version"))
|
|
||||||
value = VersionNumber.check((String) versionInfo.get("version"));
|
|
||||||
if (versionInfo.containsKey("force"))
|
|
||||||
isforceUpdate = (boolean) versionInfo.get("force");
|
|
||||||
if (versionInfo.containsKey("log"))
|
|
||||||
updateLog = (String) versionInfo.get("log");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
HMCLog.warn("Failed to check update...");
|
HMCLog.warn("Failed to check update...");
|
||||||
if (showMessage) {
|
if (showMessage)
|
||||||
MessageBox.Show(C.i18n("update.failed"));
|
MessageBox.Show(C.i18n("update.failed"));
|
||||||
}
|
} else if (VersionNumber.isOlder(base, value))
|
||||||
} else if (VersionNumber.isOlder(base, value)) {
|
|
||||||
OUT_DATED = true;
|
OUT_DATED = true;
|
||||||
}
|
if (OUT_DATED)
|
||||||
|
|
||||||
if (OUT_DATED) {
|
|
||||||
publish(value);
|
publish(value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -91,21 +66,6 @@ public final class UpdateChecker implements IUpdateChecker {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isForceUpdate() {
|
|
||||||
return isforceUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isManualUpdate() {
|
|
||||||
return isManualUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUpdateLog() {
|
|
||||||
return updateLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized OverridableSwingWorker<Map<String, String>> requestDownloadLink() {
|
public synchronized OverridableSwingWorker<Map<String, String>> requestDownloadLink() {
|
||||||
return new OverridableSwingWorker() {
|
return new OverridableSwingWorker() {
|
||||||
@@ -113,7 +73,7 @@ public final class UpdateChecker implements IUpdateChecker {
|
|||||||
protected void work() throws Exception {
|
protected void work() throws Exception {
|
||||||
if (download_link == null)
|
if (download_link == null)
|
||||||
try {
|
try {
|
||||||
download_link = C.GSON.fromJson(NetUtils.get(UPDATE_LINK_URL + type), Map.class);
|
download_link = C.GSON.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
HMCLog.warn("Failed to get update link.", e);
|
HMCLog.warn("Failed to get update link.", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
this.url = IOUtils.parseURL(p.getResult());
|
this.url = IOUtils.parseURL(p.getResult());
|
||||||
|
|
||||||
for (int repeat = 0; repeat < 6; repeat++) {
|
for (int repeat = 0; repeat < 6; repeat++) {
|
||||||
if (repeat > 0) {
|
if (repeat > 0)
|
||||||
if (failedCallbackReturnsNewURL != null) {
|
if (failedCallbackReturnsNewURL != null) {
|
||||||
URL tmp = IOUtils.parseURL(failedCallbackReturnsNewURL.apply(repeat));
|
URL tmp = IOUtils.parseURL(failedCallbackReturnsNewURL.apply(repeat));
|
||||||
if (tmp != null) {
|
if (tmp != null) {
|
||||||
@@ -126,8 +126,6 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
HMCLog.warn("Switch to: " + url);
|
HMCLog.warn("Switch to: " + url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
HMCLog.log("Downloading: " + url + ", to: " + filePath);
|
HMCLog.log("Downloading: " + url + ", to: " + filePath);
|
||||||
if (!shouldContinue)
|
if (!shouldContinue)
|
||||||
break;
|
break;
|
||||||
@@ -262,8 +260,4 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
al.add(pr);
|
al.add(pr);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFailedCallbackReturnsNewURL() {
|
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/>
|
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="btnHomepage" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="btnMCF" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCF" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
<Component id="btnClear" alignment="3" min="-2" max="-2" 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="btnClose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnHomepage" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnTieBa" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnTieBa" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnMCF" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnMCF" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
@@ -117,14 +117,12 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="btnHomepage">
|
<Component class="javax.swing.JButton" name="btnMCBBS">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" value="MCBBS"/>
|
||||||
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="logwindow.homepage" replaceFormat="C.i18n("{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnHomepageActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
|
||||||
</Events>
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="btnTieBa">
|
<Component class="javax.swing.JButton" name="btnTieBa">
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
btnClose = new javax.swing.JButton();
|
btnClose = new javax.swing.JButton();
|
||||||
btnCopy = new javax.swing.JButton();
|
btnCopy = new javax.swing.JButton();
|
||||||
lblCrash = new javax.swing.JLabel();
|
lblCrash = new javax.swing.JLabel();
|
||||||
btnHomepage = new javax.swing.JButton();
|
btnMCBBS = new javax.swing.JButton();
|
||||||
btnTieBa = new javax.swing.JButton();
|
btnTieBa = new javax.swing.JButton();
|
||||||
btnMCF = new javax.swing.JButton();
|
btnMCF = new javax.swing.JButton();
|
||||||
btnTerminateGame = new javax.swing.JButton();
|
btnTerminateGame = new javax.swing.JButton();
|
||||||
@@ -108,10 +108,10 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
|
|
||||||
lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N
|
lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N
|
||||||
|
|
||||||
btnHomepage.setText(C.i18n("logwindow.homepage")); // NOI18N
|
btnMCBBS.setText("MCBBS");
|
||||||
btnHomepage.addActionListener(new java.awt.event.ActionListener() {
|
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
btnHomepageActionPerformed(evt);
|
btnMCBBSActionPerformed(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(btnTieBa)
|
.addComponent(btnTieBa)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(btnHomepage)
|
.addComponent(btnMCBBS)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(btnMCF)
|
.addComponent(btnMCF)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
@@ -184,7 +184,7 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
.addComponent(btnClear)
|
.addComponent(btnClear)
|
||||||
.addComponent(btnClose)
|
.addComponent(btnClose)
|
||||||
.addComponent(btnCopy)
|
.addComponent(btnCopy)
|
||||||
.addComponent(btnHomepage)
|
.addComponent(btnMCBBS)
|
||||||
.addComponent(btnTieBa)
|
.addComponent(btnTieBa)
|
||||||
.addComponent(btnMCF)
|
.addComponent(btnMCF)
|
||||||
.addComponent(btnTerminateGame)
|
.addComponent(btnTerminateGame)
|
||||||
@@ -209,9 +209,9 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
Utils.setClipborad(this.txtLog.getText());
|
Utils.setClipborad(this.txtLog.getText());
|
||||||
}//GEN-LAST:event_btnCopyActionPerformed
|
}//GEN-LAST:event_btnCopyActionPerformed
|
||||||
|
|
||||||
private void btnHomepageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnHomepageActionPerformed
|
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
|
||||||
SwingUtils.openLink(C.URL_PUBLISH);
|
SwingUtils.openLink(C.URL_PUBLISH);
|
||||||
}//GEN-LAST:event_btnHomepageActionPerformed
|
}//GEN-LAST:event_btnMCBBSActionPerformed
|
||||||
|
|
||||||
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
|
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
|
||||||
SwingUtils.openLink(C.URL_TIEBA);
|
SwingUtils.openLink(C.URL_TIEBA);
|
||||||
@@ -284,7 +284,7 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
@Override
|
@Override
|
||||||
public void setVisible(boolean b) {
|
public void setVisible(boolean b) {
|
||||||
lblCrash.setVisible(false);
|
lblCrash.setVisible(false);
|
||||||
btnHomepage.setVisible(false);
|
btnMCBBS.setVisible(false);
|
||||||
btnTieBa.setVisible(false);
|
btnTieBa.setVisible(false);
|
||||||
btnMCF.setVisible(false);
|
btnMCF.setVisible(false);
|
||||||
super.setVisible(b);
|
super.setVisible(b);
|
||||||
@@ -293,13 +293,13 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
public void showAsCrashWindow(boolean out_date) {
|
public void showAsCrashWindow(boolean out_date) {
|
||||||
if (out_date) {
|
if (out_date) {
|
||||||
lblCrash.setVisible(false);
|
lblCrash.setVisible(false);
|
||||||
btnHomepage.setVisible(false);
|
btnMCBBS.setVisible(false);
|
||||||
btnTieBa.setVisible(false);
|
btnTieBa.setVisible(false);
|
||||||
btnMCF.setVisible(false);
|
btnMCF.setVisible(false);
|
||||||
lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
|
lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
|
||||||
} else {
|
} else {
|
||||||
lblCrash.setVisible(true);
|
lblCrash.setVisible(true);
|
||||||
btnHomepage.setVisible(true);
|
btnMCBBS.setVisible(true);
|
||||||
btnTieBa.setVisible(true);
|
btnTieBa.setVisible(true);
|
||||||
btnMCF.setVisible(true);
|
btnMCF.setVisible(true);
|
||||||
lblCrash.setText(C.i18n("ui.label.crashing"));
|
lblCrash.setText(C.i18n("ui.label.crashing"));
|
||||||
@@ -313,7 +313,7 @@ public class LogWindow extends javax.swing.JFrame {
|
|||||||
private javax.swing.JButton btnClose;
|
private javax.swing.JButton btnClose;
|
||||||
private javax.swing.JButton btnCopy;
|
private javax.swing.JButton btnCopy;
|
||||||
private javax.swing.JButton btnGitHub;
|
private javax.swing.JButton btnGitHub;
|
||||||
private javax.swing.JButton btnHomepage;
|
private javax.swing.JButton btnMCBBS;
|
||||||
private javax.swing.JButton btnMCF;
|
private javax.swing.JButton btnMCF;
|
||||||
private javax.swing.JButton btnTerminateGame;
|
private javax.swing.JButton btnTerminateGame;
|
||||||
private javax.swing.JButton btnTieBa;
|
private javax.swing.JButton btnTieBa;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class LogWindowOutputStream extends OutputStream {
|
|||||||
private final Level sas;
|
private final Level sas;
|
||||||
|
|
||||||
public LogWindowOutputStream(LogWindow logWindow, Level l) {
|
public LogWindowOutputStream(LogWindow logWindow, Level l) {
|
||||||
|
Objects.nonNull(logWindow);
|
||||||
|
Objects.nonNull(l);
|
||||||
txt = logWindow;
|
txt = logWindow;
|
||||||
sas = l;
|
sas = l;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=启动中
|
|||||||
ui.message.making=生成中
|
ui.message.making=生成中
|
||||||
ui.message.sure_remove=真的要删除配置%s吗?
|
ui.message.sure_remove=真的要删除配置%s吗?
|
||||||
ui.message.update_java=请更新您的Java
|
ui.message.update_java=请更新您的Java
|
||||||
ui.message.recommend_tip=点击打开链接
|
|
||||||
|
|
||||||
ui.label.settings=选项
|
ui.label.settings=选项
|
||||||
ui.label.crashing=<html>Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。</html>
|
ui.label.crashing=<html>Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。</html>
|
||||||
@@ -176,7 +175,7 @@ ui.label.crashing_out_dated=<html>Hello Minecraft! Launcher遇到了无法处理
|
|||||||
ui.label.failed_set=设置失败:
|
ui.label.failed_set=设置失败:
|
||||||
|
|
||||||
download=下载
|
download=下载
|
||||||
download.mojang=Mojang官方
|
download.mojang=官方
|
||||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||||
download.rapid_data=RapidData (锐网云计算, https://www.rapiddata.org/)
|
download.rapid_data=RapidData (锐网云计算, https://www.rapiddata.org/)
|
||||||
download.not_200=下载失败,回复码
|
download.not_200=下载失败,回复码
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=输入要生成脚本的文件名
|
|||||||
mainwindow.make_launch_succeed=启动脚本已生成完毕:
|
mainwindow.make_launch_succeed=启动脚本已生成完毕:
|
||||||
mainwindow.no_version=未找到任何版本,是否进入游戏下载?
|
mainwindow.no_version=未找到任何版本,是否进入游戏下载?
|
||||||
|
|
||||||
launcher.about=<html>默认背景图感谢gamerteam提供。<br/>关于作者:<br/>主页:http://www.hmclsoft.com<br/>邮箱:contact@hmclsoft.com<br/>欢迎提交Bug哦<br/>Copyright (c) 2013-2016 HMCLSoft.<br/>免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。<br/>本启动器在GPLv3协议下开源:https://github.com/mclauncher/HMCL,感谢issues和pull requests贡献者<br/>本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。</html>
|
launcher.about=<html>默认背景图感谢gamerteam提供。<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">如果您希望本软件继续发展,请赞助</a><br/>关于作者:<br/>百度ID:huanghongxun20<br/>mcbbs:huanghongxun<br/>邮箱:huanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>欢迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br/>免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。<br/>本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br/>本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。</html>
|
||||||
launcher.download_source=下载源
|
launcher.download_source=下载源
|
||||||
launcher.homepage=官网
|
|
||||||
launcher.background_location=背景地址
|
launcher.background_location=背景地址
|
||||||
launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。
|
launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。
|
||||||
launcher.versions_json_not_matched=版本%s格式不规范!该版本文件夹下有json:%s,是否更名这个文件来规范格式?
|
launcher.versions_json_not_matched=版本%s格式不规范!该版本文件夹下有json:%s,是否更名这个文件来规范格式?
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=启用窗口阴影
|
|||||||
launcher.theme=主题
|
launcher.theme=主题
|
||||||
launcher.proxy=代理
|
launcher.proxy=代理
|
||||||
launcher.decorated=启用窗口边框(Linux下可解决程序界面全灰问题)
|
launcher.decorated=启用窗口边框(Linux下可解决程序界面全灰问题)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">整合包作者帮助</a></html>
|
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">整合包作者帮助</a></html>
|
||||||
launcher.enable_animation=启用动态效果
|
launcher.enable_animation=启用动态效果
|
||||||
launcher.lang=语言
|
launcher.lang=语言
|
||||||
launcher.restart=本界面选项需要重启本启动器生效
|
launcher.restart=本界面选项需要重启本启动器生效
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=是否更新?
|
|||||||
update.newest_version=最新版本为:
|
update.newest_version=最新版本为:
|
||||||
update.failed=检查更新失败
|
update.failed=检查更新失败
|
||||||
update.found=(发现更新!)
|
update.found=(发现更新!)
|
||||||
update.ignore=不再提醒此版本更新
|
|
||||||
|
|
||||||
logwindow.terminate_game=结束游戏进程
|
logwindow.terminate_game=结束游戏进程
|
||||||
logwindow.tieba=贴吧
|
logwindow.tieba=贴吧
|
||||||
logwindow.title=日志
|
logwindow.title=日志
|
||||||
logwindow.homepage=官网
|
|
||||||
|
|
||||||
selector.choose=选择
|
selector.choose=选择
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=\u542f\u52a8\u4e2d
|
|||||||
ui.message.making=\u751f\u6210\u4e2d
|
ui.message.making=\u751f\u6210\u4e2d
|
||||||
ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f
|
ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f
|
||||||
ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java
|
ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java
|
||||||
ui.message.recommend_tip=\u70b9\u51fb\u6253\u5f00\u94fe\u63a5
|
|
||||||
|
|
||||||
ui.label.settings=\u9009\u9879
|
ui.label.settings=\u9009\u9879
|
||||||
ui.label.crashing=<html>Hello Minecraft!\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u8bf7\u590d\u5236\u4e0b\u5217\u5185\u5bb9\u5e76\u901a\u8fc7mcbbs\u3001\u8d34\u5427\u3001Github\u6216Minecraft Forum\u53cd\u9988bug\u3002</html>
|
ui.label.crashing=<html>Hello Minecraft!\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u8bf7\u590d\u5236\u4e0b\u5217\u5185\u5bb9\u5e76\u901a\u8fc7mcbbs\u3001\u8d34\u5427\u3001Github\u6216Minecraft Forum\u53cd\u9988bug\u3002</html>
|
||||||
@@ -176,7 +175,7 @@ ui.label.crashing_out_dated=<html>Hello Minecraft! Launcher\u9047\u5230\u4e86\u6
|
|||||||
ui.label.failed_set=\u8bbe\u7f6e\u5931\u8d25\uff1a
|
ui.label.failed_set=\u8bbe\u7f6e\u5931\u8d25\uff1a
|
||||||
|
|
||||||
download=\u4e0b\u8f7d
|
download=\u4e0b\u8f7d
|
||||||
download.mojang=Mojang\u5b98\u65b9
|
download.mojang=\u5b98\u65b9
|
||||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||||
download.rapid_data=RapidData (\u9510\u7f51\u4e91\u8ba1\u7b97, https://www.rapiddata.org/)
|
download.rapid_data=RapidData (\u9510\u7f51\u4e91\u8ba1\u7b97, https://www.rapiddata.org/)
|
||||||
download.not_200=\u4e0b\u8f7d\u5931\u8d25\uff0c\u56de\u590d\u7801
|
download.not_200=\u4e0b\u8f7d\u5931\u8d25\uff0c\u56de\u590d\u7801
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=\u8f93\u5165\u8981\u751f\u6210\u811a\u672c\u7684\u6
|
|||||||
mainwindow.make_launch_succeed=\u542f\u52a8\u811a\u672c\u5df2\u751f\u6210\u5b8c\u6bd5:
|
mainwindow.make_launch_succeed=\u542f\u52a8\u811a\u672c\u5df2\u751f\u6210\u5b8c\u6bd5:
|
||||||
mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u8fdb\u5165\u6e38\u620f\u4e0b\u8f7d\uff1f
|
mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u8fdb\u5165\u6e38\u620f\u4e0b\u8f7d\uff1f
|
||||||
|
|
||||||
launcher.about=<html>\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002<br/>\u5173\u4e8e\u4f5c\u8005\uff1a<br/>\u4e3b\u9875\uff1ahttp://www.hmclsoft.com<br/>\u90ae\u7bb1\uff1acontact@hmclsoft.com<br/>\u6b22\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 HMCLSoft.<br/>\u514d\u8d23\u58f0\u660e\uff1aMinecraft\u8f6f\u4ef6\u7248\u6743\u5f52Mojang AB\u6240\u6709\uff0c\u4f7f\u7528\u672c\u8f6f\u4ef6\u4ea7\u751f\u7684\u7248\u6743\u95ee\u9898\u672c\u8f6f\u4ef6\u5236\u4f5c\u65b9\u6982\u4e0d\u8d1f\u8d23\u3002<br/>\u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90\uff1ahttps://github.com/mclauncher/HMCL\uff0c\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br/>\u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002</html>
|
launcher.about=<html>\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">\u5982\u679c\u60a8\u5e0c\u671b\u672c\u8f6f\u4ef6\u7ee7\u7eed\u53d1\u5c55\uff0c\u8bf7\u8d5e\u52a9</a><br/>\u5173\u4e8e\u4f5c\u8005\uff1a<br/>\u767e\u5ea6ID\uff1ahuanghongxun20<br/>mcbbs\uff1ahuanghongxun<br/>\u90ae\u7bb1\uff1ahuanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>\u6b22\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br/>\u514d\u8d23\u58f0\u660e\uff1aMinecraft\u8f6f\u4ef6\u7248\u6743\u5f52Mojang AB\u6240\u6709\uff0c\u4f7f\u7528\u672c\u8f6f\u4ef6\u4ea7\u751f\u7684\u7248\u6743\u95ee\u9898\u672c\u8f6f\u4ef6\u5236\u4f5c\u65b9\u6982\u4e0d\u8d1f\u8d23\u3002<br/>\u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90:https://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br/>\u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002</html>
|
||||||
launcher.download_source=\u4e0b\u8f7d\u6e90
|
launcher.download_source=\u4e0b\u8f7d\u6e90
|
||||||
launcher.homepage=\u5b98\u7f51
|
|
||||||
launcher.background_location=\u80cc\u666f\u5730\u5740
|
launcher.background_location=\u80cc\u666f\u5730\u5740
|
||||||
launcher.exit_failed=\u5f3a\u5236\u9000\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5bfc\u81f4\u7684\uff0c\u65e0\u6cd5\u89e3\u51b3\u3002
|
launcher.exit_failed=\u5f3a\u5236\u9000\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5bfc\u81f4\u7684\uff0c\u65e0\u6cd5\u89e3\u51b3\u3002
|
||||||
launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u89c4\u8303\uff01\u8be5\u7248\u672c\u6587\u4ef6\u5939\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u8fd9\u4e2a\u6587\u4ef6\u6765\u89c4\u8303\u683c\u5f0f\uff1f
|
launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u89c4\u8303\uff01\u8be5\u7248\u672c\u6587\u4ef6\u5939\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u8fd9\u4e2a\u6587\u4ef6\u6765\u89c4\u8303\u683c\u5f0f\uff1f
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71
|
|||||||
launcher.theme=\u4e3b\u9898
|
launcher.theme=\u4e3b\u9898
|
||||||
launcher.proxy=\u4ee3\u7406
|
launcher.proxy=\u4ee3\u7406
|
||||||
launcher.decorated=\u542f\u7528\u7a97\u53e3\u8fb9\u6846(Linux\u4e0b\u53ef\u89e3\u51b3\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u95ee\u9898)
|
launcher.decorated=\u542f\u7528\u7a97\u53e3\u8fb9\u6846(Linux\u4e0b\u53ef\u89e3\u51b3\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u95ee\u9898)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
|
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
|
||||||
launcher.enable_animation=\u542f\u7528\u52a8\u6001\u6548\u679c
|
launcher.enable_animation=\u542f\u7528\u52a8\u6001\u6548\u679c
|
||||||
launcher.lang=\u8bed\u8a00
|
launcher.lang=\u8bed\u8a00
|
||||||
launcher.restart=\u672c\u754c\u9762\u9009\u9879\u9700\u8981\u91cd\u542f\u672c\u542f\u52a8\u5668\u751f\u6548
|
launcher.restart=\u672c\u754c\u9762\u9009\u9879\u9700\u8981\u91cd\u542f\u672c\u542f\u52a8\u5668\u751f\u6548
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f
|
|||||||
update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
||||||
update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
||||||
update.found=(\u53d1\u73b0\u66f4\u65b0!)
|
update.found=(\u53d1\u73b0\u66f4\u65b0!)
|
||||||
update.ignore=\u4e0d\u518d\u63d0\u9192\u6b64\u7248\u672c\u66f4\u65b0
|
|
||||||
|
|
||||||
logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b
|
logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b
|
||||||
logwindow.tieba=\u8d34\u5427
|
logwindow.tieba=\u8d34\u5427
|
||||||
logwindow.title=\u65e5\u5fd7
|
logwindow.title=\u65e5\u5fd7
|
||||||
logwindow.homepage=\u5b98\u7f51
|
|
||||||
|
|
||||||
selector.choose=\u9009\u62e9
|
selector.choose=\u9009\u62e9
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=Launching...
|
|||||||
ui.message.making=Generating...
|
ui.message.making=Generating...
|
||||||
ui.message.sure_remove=Sure to remove profile %s?
|
ui.message.sure_remove=Sure to remove profile %s?
|
||||||
ui.message.update_java=Please upgrade your Java.
|
ui.message.update_java=Please upgrade your Java.
|
||||||
ui.message.recommend_tip=Click to open link
|
|
||||||
|
|
||||||
ui.label.settings=Settings
|
ui.label.settings=Settings
|
||||||
ui.label.crashing=<html>Hello Minecraft! Launcher has crashed!</html>
|
ui.label.crashing=<html>Hello Minecraft! Launcher has crashed!</html>
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=Enter the script name.
|
|||||||
mainwindow.make_launch_succeed=Finished script creation.
|
mainwindow.make_launch_succeed=Finished script creation.
|
||||||
mainwindow.no_version=No version found. Switch to Game Downloads Tab?
|
mainwindow.no_version=No version found. Switch to Game Downloads Tab?
|
||||||
|
|
||||||
launcher.about=<html>About Author<br/>Homepage: http://www.hmclsoft.com<br/>Email: contact@hmclsoft.com<br/>Copyright (c) 2013 HMCLSoft.<br/>Opened source under GPL v3 license: http://github.com/mclauncher/HMCL<br/>This software used project Gson which is under Apache License 2.0, thanks contributors.</html>
|
launcher.about=<html>About Author<br/>Email:huanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>Copyright (c) 2013 huangyuhui<br/>Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/<br/>This software used project Gson which is under Apache License 2.0, thanks contributors.</html>
|
||||||
launcher.download_source=Download Source
|
launcher.download_source=Download Source
|
||||||
launcher.homepage=Homepage
|
|
||||||
launcher.background_location=Background Location
|
launcher.background_location=Background Location
|
||||||
launcher.exit_failed=Failed to shutdown.
|
launcher.exit_failed=Failed to shutdown.
|
||||||
launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem?
|
launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem?
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=Enable Window Shadow
|
|||||||
launcher.theme=Theme
|
launcher.theme=Theme
|
||||||
launcher.proxy=Proxy
|
launcher.proxy=Proxy
|
||||||
launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS)
|
launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">Documentations for modpacks.</a></html>
|
launcher.modpack=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">Documentations for modpacks.</a></html>
|
||||||
launcher.enable_animation=Enable Animation
|
launcher.enable_animation=Enable Animation
|
||||||
launcher.lang=Language
|
launcher.lang=Language
|
||||||
launcher.restart=Options will be in operations only if restart this app.
|
launcher.restart=Options will be in operations only if restart this app.
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=Are you willing to upgrade this app?
|
|||||||
update.newest_version=Newest version:
|
update.newest_version=Newest version:
|
||||||
update.failed=Failed to check for updates.
|
update.failed=Failed to check for updates.
|
||||||
update.found=(Found Update!)
|
update.found=(Found Update!)
|
||||||
update.ignore=Do not remind this version update.
|
|
||||||
|
|
||||||
logwindow.terminate_game=Terminate Game
|
logwindow.terminate_game=Terminate Game
|
||||||
logwindow.tieba=Baidu Tieba
|
logwindow.tieba=Baidu Tieba
|
||||||
logwindow.title=Log
|
logwindow.title=Log
|
||||||
logwindow.homepage=Homepage
|
|
||||||
|
|
||||||
selector.choose=Choose
|
selector.choose=Choose
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=Launching...
|
|||||||
ui.message.making=Generating...
|
ui.message.making=Generating...
|
||||||
ui.message.sure_remove=Sure to remove profile %s?
|
ui.message.sure_remove=Sure to remove profile %s?
|
||||||
ui.message.update_java=Please upgrade your Java.
|
ui.message.update_java=Please upgrade your Java.
|
||||||
ui.message.recommend_tip=Click to open link
|
|
||||||
|
|
||||||
ui.label.settings=Settings
|
ui.label.settings=Settings
|
||||||
ui.label.crashing=<html>Hello Minecraft! Launcher has crashed!</html>
|
ui.label.crashing=<html>Hello Minecraft! Launcher has crashed!</html>
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=Enter the script name.
|
|||||||
mainwindow.make_launch_succeed=Finished script creation.
|
mainwindow.make_launch_succeed=Finished script creation.
|
||||||
mainwindow.no_version=No version found. Switch to Game Downloads Tab?
|
mainwindow.no_version=No version found. Switch to Game Downloads Tab?
|
||||||
|
|
||||||
launcher.about=<html>About Author<br/>Homepage: http://www.hmclsoft.com<br/>Email: contact@hmclsoft.com<br/>Copyright (c) 2013 HMCLSoft.<br/>Opened source under GPL v3 license: http://github.com/mclauncher/HMCL<br/>This software used project Gson which is under Apache License 2.0, thanks contributors.</html>
|
launcher.about=<html>About Author<br/>Email\uff1ahuanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>Copyright (c) 2013 huangyuhui<br/>Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/<br/>This software used project Gson which is under Apache License 2.0, thanks contributors.</html>
|
||||||
launcher.download_source=Download Source
|
launcher.download_source=Download Source
|
||||||
launcher.homepage=Homepage
|
|
||||||
launcher.background_location=Background Location
|
launcher.background_location=Background Location
|
||||||
launcher.exit_failed=Failed to shutdown.
|
launcher.exit_failed=Failed to shutdown.
|
||||||
launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem?
|
launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem?
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=Enable Window Shadow
|
|||||||
launcher.theme=Theme
|
launcher.theme=Theme
|
||||||
launcher.proxy=Proxy
|
launcher.proxy=Proxy
|
||||||
launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS)
|
launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">Documentations for modpacks.</a></html>
|
launcher.modpack=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">Documentations for modpacks.</a></html>
|
||||||
launcher.enable_animation=Enable Animation
|
launcher.enable_animation=Enable Animation
|
||||||
launcher.lang=Language
|
launcher.lang=Language
|
||||||
launcher.restart=Options will be in operations only if restart this app.
|
launcher.restart=Options will be in operations only if restart this app.
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=Are you willing to upgrade this app?
|
|||||||
update.newest_version=Newest version:
|
update.newest_version=Newest version:
|
||||||
update.failed=Failed to check for updates.
|
update.failed=Failed to check for updates.
|
||||||
update.found=(Found Update!)
|
update.found=(Found Update!)
|
||||||
update.ignore=Do not remind this version update.
|
|
||||||
|
|
||||||
logwindow.terminate_game=Terminate Game
|
logwindow.terminate_game=Terminate Game
|
||||||
logwindow.tieba=Baidu Tieba
|
logwindow.tieba=Baidu Tieba
|
||||||
logwindow.title=Log
|
logwindow.title=Log
|
||||||
logwindow.homepage=Homepage
|
|
||||||
|
|
||||||
selector.choose=Choose
|
selector.choose=Choose
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=啟動中
|
|||||||
ui.message.making=生成中
|
ui.message.making=生成中
|
||||||
ui.message.sure_remove=真的要删除配置%s吗?
|
ui.message.sure_remove=真的要删除配置%s吗?
|
||||||
ui.message.update_java=请更新您的Java
|
ui.message.update_java=请更新您的Java
|
||||||
ui.message.recommend_tip=點擊打開連接
|
|
||||||
|
|
||||||
ui.label.settings=選項
|
ui.label.settings=選項
|
||||||
ui.label.crashing=<html>Hello Minecraft! Launcher遇到了無法處理的錯誤,請複制下列內容並通過mcbbs、貼吧或Minecraft Forum反饋bug。 </html>
|
ui.label.crashing=<html>Hello Minecraft! Launcher遇到了無法處理的錯誤,請複制下列內容並通過mcbbs、貼吧或Minecraft Forum反饋bug。 </html>
|
||||||
@@ -176,7 +175,7 @@ ui.label.crashing_out_dated=<html>Hello Minecraft! Launcher遇到了無法處理
|
|||||||
ui.label.failed_set=設定失敗:
|
ui.label.failed_set=設定失敗:
|
||||||
|
|
||||||
download=下載
|
download=下載
|
||||||
download.mojang=Mojang官方
|
download.mojang=官方
|
||||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||||
download.rapid_data=RapidData (銳網雲計算, https://www.rapiddata.org/)
|
download.rapid_data=RapidData (銳網雲計算, https://www.rapiddata.org/)
|
||||||
download.not_200=下載失敗,回复码
|
download.not_200=下載失敗,回复码
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=輸入要生成腳本的資料名
|
|||||||
mainwindow.make_launch_succeed=啟動腳本已生成完畢:
|
mainwindow.make_launch_succeed=啟動腳本已生成完畢:
|
||||||
mainwindow.no_version=未找到任何版本,是否進入遊戲下載?
|
mainwindow.no_version=未找到任何版本,是否進入遊戲下載?
|
||||||
|
|
||||||
launcher.about=<html>默認背景圖感謝gamerteam提供。<br/>關於作者:<br/>主頁:http://www.hmclsoft.com<br/>郵箱:contact@hmclsoft.com<br/>歡迎提交Bug哦<br/>Copyright (c) 2013-2016 HMCLSoft.<br/>免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。<br/>本啟動器在GPLv3協議下開源:http://github.com/mclauncher/HMCL,感谢issues和pull requests贡献者<br/>本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。</html>
|
launcher.about=<html>默認背景圖感謝gamerteam提供。<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">如果您希望本軟件繼續發展,請贊助</a><br>關於作者:<br>百度ID:huanghongxun20<br>mcbbs:huanghongxun<br>郵箱:huanghongxun2008@126.com<br>Minecraft Forum ID: klkl6523<br>歡迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br>免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。<br>本啟動器在GPLv3協議下開源:http://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br>本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。</html>
|
||||||
launcher.download_source=下載源
|
launcher.download_source=下載源
|
||||||
launcher.homepage=官網
|
|
||||||
launcher.background_location=背景地址
|
launcher.background_location=背景地址
|
||||||
launcher.exit_failed=強制退出失敗,可能是Forge 1.7.10及更高版本導致的,無法解決。
|
launcher.exit_failed=強制退出失敗,可能是Forge 1.7.10及更高版本導致的,無法解決。
|
||||||
launcher.versions_json_not_matched=版本%s格式不規範!該版本資料夾下有json:%s,是否更名這個資料來規範格式?
|
launcher.versions_json_not_matched=版本%s格式不規範!該版本資料夾下有json:%s,是否更名這個資料來規範格式?
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=启用窗口阴影
|
|||||||
launcher.theme=主题
|
launcher.theme=主题
|
||||||
launcher.proxy=代理
|
launcher.proxy=代理
|
||||||
launcher.decorated=啟用窗口邊框(Linux下可解決程序界面全灰問題)
|
launcher.decorated=啟用窗口邊框(Linux下可解決程序界面全灰問題)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">整合包作者帮助</a></html>
|
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">整合包作者帮助</a></html>
|
||||||
launcher.enable_animation=啟用動態效果
|
launcher.enable_animation=啟用動態效果
|
||||||
launcher.lang=語言
|
launcher.lang=語言
|
||||||
launcher.restart=本界面選項需要重啟本啟動器生效
|
launcher.restart=本界面選項需要重啟本啟動器生效
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=是否更新?
|
|||||||
update.newest_version=最新版本為:
|
update.newest_version=最新版本為:
|
||||||
update.failed=檢查更新失敗
|
update.failed=檢查更新失敗
|
||||||
update.found=(發現更新!)
|
update.found=(發現更新!)
|
||||||
update.ignore=不再提醒此版本更新
|
|
||||||
|
|
||||||
logwindow.terminate_game=結束遊戲進程
|
logwindow.terminate_game=結束遊戲進程
|
||||||
logwindow.tieba=貼吧
|
logwindow.tieba=貼吧
|
||||||
logwindow.title=日志
|
logwindow.title=日志
|
||||||
logwindow.homepage=官網
|
|
||||||
|
|
||||||
selector.choose=選擇
|
selector.choose=選擇
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ui.message.launching=\u555f\u52d5\u4e2d
|
|||||||
ui.message.making=\u751f\u6210\u4e2d
|
ui.message.making=\u751f\u6210\u4e2d
|
||||||
ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f
|
ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f
|
||||||
ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java
|
ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java
|
||||||
ui.message.recommend_tip=\u9ede\u64ca\u6253\u958b\u9023\u63a5
|
|
||||||
|
|
||||||
ui.label.settings=\u9078\u9805
|
ui.label.settings=\u9078\u9805
|
||||||
ui.label.crashing=<html>Hello Minecraft! Launcher\u9047\u5230\u4e86\u7121\u6cd5\u8655\u7406\u7684\u932f\u8aa4\uff0c\u8acb\u8907\u5236\u4e0b\u5217\u5167\u5bb9\u4e26\u901a\u904emcbbs\u3001\u8cbc\u5427\u6216Minecraft Forum\u53cd\u994bbug\u3002 </html>
|
ui.label.crashing=<html>Hello Minecraft! Launcher\u9047\u5230\u4e86\u7121\u6cd5\u8655\u7406\u7684\u932f\u8aa4\uff0c\u8acb\u8907\u5236\u4e0b\u5217\u5167\u5bb9\u4e26\u901a\u904emcbbs\u3001\u8cbc\u5427\u6216Minecraft Forum\u53cd\u994bbug\u3002 </html>
|
||||||
@@ -176,7 +175,7 @@ ui.label.crashing_out_dated=<html>Hello Minecraft! Launcher\u9047\u5230\u4e86\u7
|
|||||||
ui.label.failed_set=\u8a2d\u5b9a\u5931\u6557\uff1a
|
ui.label.failed_set=\u8a2d\u5b9a\u5931\u6557\uff1a
|
||||||
|
|
||||||
download=\u4e0b\u8f09
|
download=\u4e0b\u8f09
|
||||||
download.mojang=Mojang\u5b98\u65b9
|
download.mojang=\u5b98\u65b9
|
||||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||||
download.rapid_data=RapidData (\u92b3\u7db2\u96f2\u8a08\u7b97, https://www.rapiddata.org/)
|
download.rapid_data=RapidData (\u92b3\u7db2\u96f2\u8a08\u7b97, https://www.rapiddata.org/)
|
||||||
download.not_200=\u4e0b\u8f09\u5931\u6557\uff0c\u56de\u590d\u7801
|
download.not_200=\u4e0b\u8f09\u5931\u6557\uff0c\u56de\u590d\u7801
|
||||||
@@ -299,9 +298,8 @@ mainwindow.enter_script_name=\u8f38\u5165\u8981\u751f\u6210\u8173\u672c\u7684\u8
|
|||||||
mainwindow.make_launch_succeed=\u555f\u52d5\u8173\u672c\u5df2\u751f\u6210\u5b8c\u7562:
|
mainwindow.make_launch_succeed=\u555f\u52d5\u8173\u672c\u5df2\u751f\u6210\u5b8c\u7562:
|
||||||
mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u9032\u5165\u904a\u6232\u4e0b\u8f09\uff1f
|
mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u9032\u5165\u904a\u6232\u4e0b\u8f09\uff1f
|
||||||
|
|
||||||
launcher.about=<html>\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002<br/>\u95dc\u65bc\u4f5c\u8005\uff1a<br/>\u4e3b\u9801\uff1ahttp://www.hmclsoft.com<br/>\u90f5\u7bb1\uff1acontact@hmclsoft.com<br/>\u6b61\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 HMCLSoft.<br/>\u514d\u8cac\u8072\u660e\uff1aMinecraft\u8edf\u9ad4\u7248\u6b0a\u6b78Mojang AB\u6240\u6709\uff0c\u904a\u6232\u7531\u65bc\u8aa4\u64cd\u4f5c\u672c\u555f\u52d5\u5668\u800c\u4e1f\u5931\u6578\u64da\u7684\u6982\u4e0d\u8ca0\u8cac\u3002<br/>\u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90\uff1ahttp://github.com/mclauncher/HMCL\uff0c\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br>\u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002</html>
|
launcher.about=<html>\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">\u5982\u679c\u60a8\u5e0c\u671b\u672c\u8edf\u4ef6\u7e7c\u7e8c\u767c\u5c55\uff0c\u8acb\u8d0a\u52a9</a><br>\u95dc\u65bc\u4f5c\u8005\uff1a<br>\u767e\u5ea6ID\uff1ahuanghongxun20<br>mcbbs\uff1ahuanghongxun<br>\u90f5\u7bb1\uff1ahuanghongxun2008@126.com<br>Minecraft Forum ID: klkl6523<br>\u6b61\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br>\u514d\u8cac\u8072\u660e\uff1aMinecraft\u8edf\u9ad4\u7248\u6b0a\u6b78Mojang AB\u6240\u6709\uff0c\u904a\u6232\u7531\u65bc\u8aa4\u64cd\u4f5c\u672c\u555f\u52d5\u5668\u800c\u4e1f\u5931\u6578\u64da\u7684\u6982\u4e0d\u8ca0\u8cac\u3002<br>\u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90:http://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br>\u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002</html>
|
||||||
launcher.download_source=\u4e0b\u8f09\u6e90
|
launcher.download_source=\u4e0b\u8f09\u6e90
|
||||||
launcher.homepage=\u5b98\u7db2
|
|
||||||
launcher.background_location=\u80cc\u666f\u5730\u5740
|
launcher.background_location=\u80cc\u666f\u5730\u5740
|
||||||
launcher.exit_failed=\u5f37\u5236\u9000\u51fa\u5931\u6557\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5c0e\u81f4\u7684\uff0c\u7121\u6cd5\u89e3\u6c7a\u3002
|
launcher.exit_failed=\u5f37\u5236\u9000\u51fa\u5931\u6557\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5c0e\u81f4\u7684\uff0c\u7121\u6cd5\u89e3\u6c7a\u3002
|
||||||
launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u898f\u7bc4\uff01\u8a72\u7248\u672c\u8cc7\u6599\u593e\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u9019\u500b\u8cc7\u6599\u4f86\u898f\u7bc4\u683c\u5f0f\uff1f
|
launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u898f\u7bc4\uff01\u8a72\u7248\u672c\u8cc7\u6599\u593e\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u9019\u500b\u8cc7\u6599\u4f86\u898f\u7bc4\u683c\u5f0f\uff1f
|
||||||
@@ -314,7 +312,7 @@ launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71
|
|||||||
launcher.theme=\u4e3b\u9898
|
launcher.theme=\u4e3b\u9898
|
||||||
launcher.proxy=\u4ee3\u7406
|
launcher.proxy=\u4ee3\u7406
|
||||||
launcher.decorated=\u555f\u7528\u7a97\u53e3\u908a\u6846(Linux\u4e0b\u53ef\u89e3\u6c7a\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u554f\u984c)
|
launcher.decorated=\u555f\u7528\u7a97\u53e3\u908a\u6846(Linux\u4e0b\u53ef\u89e3\u6c7a\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u554f\u984c)
|
||||||
launcher.modpack=<html><a href="http://client.api.mcgogogo.com:81/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
|
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
|
||||||
launcher.enable_animation=\u555f\u7528\u52d5\u614b\u6548\u679c
|
launcher.enable_animation=\u555f\u7528\u52d5\u614b\u6548\u679c
|
||||||
launcher.lang=\u8a9e\u8a00
|
launcher.lang=\u8a9e\u8a00
|
||||||
launcher.restart=\u672c\u754c\u9762\u9078\u9805\u9700\u8981\u91cd\u555f\u672c\u555f\u52d5\u5668\u751f\u6548
|
launcher.restart=\u672c\u754c\u9762\u9078\u9805\u9700\u8981\u91cd\u555f\u672c\u555f\u52d5\u5668\u751f\u6548
|
||||||
@@ -371,12 +369,10 @@ update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f
|
|||||||
update.newest_version=\u6700\u65b0\u7248\u672c\u70ba\uff1a
|
update.newest_version=\u6700\u65b0\u7248\u672c\u70ba\uff1a
|
||||||
update.failed=\u6aa2\u67e5\u66f4\u65b0\u5931\u6557
|
update.failed=\u6aa2\u67e5\u66f4\u65b0\u5931\u6557
|
||||||
update.found=(\u767c\u73fe\u66f4\u65b0!)
|
update.found=(\u767c\u73fe\u66f4\u65b0!)
|
||||||
update.ignore=\u4e0d\u518d\u63d0\u9192\u6b64\u7248\u672c\u66f4\u65b0
|
|
||||||
|
|
||||||
logwindow.terminate_game=\u7d50\u675f\u904a\u6232\u9032\u7a0b
|
logwindow.terminate_game=\u7d50\u675f\u904a\u6232\u9032\u7a0b
|
||||||
logwindow.tieba=\u8cbc\u5427
|
logwindow.tieba=\u8cbc\u5427
|
||||||
logwindow.title=\u65e5\u5fd7
|
logwindow.title=\u65e5\u5fd7
|
||||||
logwindow.homepage=\u5b98\u7db2
|
|
||||||
|
|
||||||
selector.choose=\u9078\u64c7
|
selector.choose=\u9078\u64c7
|
||||||
|
|
||||||
|
|||||||
4
LICENSE
4
LICENSE
@@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
|
|||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
Hello Minecraft! Launcher, a Minecraft Launcher which is easy to use.
|
Hello Minecraft! Launcher, a Minecraft Launcher which is easy to use.
|
||||||
Copyright (C) 2016 HMCLSoft.
|
Copyright (C) 2014 huangyuhui
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|||||||
If the program does terminal interaction, make it output a short
|
If the program does terminal interaction, make it output a short
|
||||||
notice like this when it starts in an interactive mode:
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
Hello Minecraft! Launcher Copyright (C) 2016 HMCLSoft.
|
Hello Minecraft! Launcher Copyright (C) 2014 huangyuhui
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
# Hello Minecraft! Launcher [](https://travis-ci.org/mclauncher/HMCL)
|
# Hello Minecraft! Launcher [](https://travis-ci.org/huanghongxun/HMCL)
|
||||||
开源协议为GPL v3, 详情参见http://www.gnu.org/licenses/gpl.html
|
开源协议为GPL v3, 详情参见http://www.gnu.org/licenses/gpl.html
|
||||||
|
|
||||||
## 介绍
|
## 介绍
|
||||||
|
|
||||||
HMCL是一个Minecraft启动器,支持Mod管理,游戏定制,自动安装,整合包制作,界面主题定制等功能。
|
HMCL是一个Minecraft启动器,支持Mod管理,游戏定制,自动安装,整合包制作,界面主题定制等功能。
|
||||||
|
并且一天的使用次数在工作日时有40万左右、节假日有150万左右的使用次数,也就是说日活跃用户在10万以上。
|
||||||
但是本项目的代码不够完善,希望有更多的人能加入HMCL的开发。
|
但是本项目的代码不够完善,希望有更多的人能加入HMCL的开发。
|
||||||
|
|
||||||
## 贡献
|
## 贡献
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Hello Minecraft! Launcher.
|
* Hello Minecraft! Launcher.
|
||||||
* Copyright (C) 2016 HMCLSoft.
|
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
Reference in New Issue
Block a user