Compare commits

..
25 Commits
Author SHA1 Message Date
南宫临风 130b950878 update version 2016-08-29 17:13:00 +08:00
南宫临风 c0b935e3f1 迁移崩溃收集
改进推荐内容关闭策略
2016-08-25 14:33:40 +08:00
南宫临风 90451e6da9 最大限度的捕获异常,防止客户端崩溃
添加关闭推荐内容按钮
2016-08-24 13:46:06 +08:00
南宫临风 6db34fcdc7 修正地址解析问题 2016-08-22 10:23:27 +08:00
南宫临风 5bb53622ca Update HMCL version 2016-08-18 11:36:36 +08:00
南宫临风 b9308f060f oschina的Maven下载失效 2016-08-18 11:25:03 +08:00
南宫临风 f715367849 Update HMCL version 2016-07-12 19:07:15 +08:00
南宫临风 07b757b3c1 try fix travis 2016-07-12 18:03:04 +08:00
南宫临风 3325e393bc try fix travis file 2016-07-12 17:51:07 +08:00
南宫临风 48a8c99c83 Update travis 2016-07-12 16:17:09 +08:00
南宫临风 8d687158f6 Update travis 2016-07-12 15:28:55 +08:00
南宫临风 f966793490 Fix travis 2016-07-12 15:06:03 +08:00
南宫临风 d824122219 Fix travis-ci file 2016-07-12 14:49:32 +08:00
南宫临风 65900b5881 update tag style 2016-07-12 14:37:13 +08:00
南宫临风 e6ed1eab71 难用的travis-ci 2016-07-12 14:34:14 +08:00
南宫临风 1a3c31a141 Fix Library resolve bug 2016-07-12 14:17:17 +08:00
南宫临风 c0ef592f72 Restore icon and must manually add tag 2016-07-12 10:37:18 +08:00
南宫临风 5d2b4d435f Modify download type 2016-07-11 16:59:06 +08:00
南宫临风 fd5b5ebd8d Try test travis 2016-07-11 15:23:10 +08:00
南宫临风 2f42873793 Fix gradle build file 2016-07-11 11:54:22 +08:00
南宫临风 3b4b63e57b Modify publish link 2016-07-11 11:47:12 +08:00
南宫临风 c33a99d9ed show update log 2016-07-09 22:04:43 +08:00
南宫临风 b6be41e5c5 update git ignore file 2016-07-09 21:02:57 +08:00
南宫临风 bd4c07a013 read buildNumber from travis 2016-07-09 21:01:37 +08:00
南宫临风 ba763b2d2a Synchronize version.properties 2016-07-08 20:40:55 +08:00
28 changed files with 428 additions and 238 deletions

No files matched your search

+3 -1
View File
@@ -26,4 +26,6 @@ HMCLServer/
HMCSM/build/
MetroLookAndFeel/build/
/HMCUtils/build/
/HMCLaF/build/
/HMCLaF/build/
HMCL/version.properties
.idea/
+5 -12
View File
@@ -1,14 +1,7 @@
language: java
sudo: false
jdk:
- 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:
provider: releases
api_key: ${DEPLOY_REPO}
@@ -20,7 +13,9 @@ deploy:
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}-MacOSApp.zip
on:
tags: false
repo: mclauncher/HMCL
branch: master
tags: true
skip_cleanup: true
install: echo "skip 'gradle assemble' step"
script: gradle build --continue
@@ -29,6 +24,4 @@ before_cache:
cache:
directories:
- "$HOME/.gradle/caches/"
- "$HOME/.gradle/wrapper/"
git:
depth: 1
- "$HOME/.gradle/wrapper/"
+30 -12
View File
@@ -27,6 +27,7 @@ buildscript {
classpath 'net.sf.proguard:proguard-gradle:4.10'
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
classpath 'com.google.code.gson:gson:2.2.4'
}
}
}
@@ -38,6 +39,7 @@ plugins {
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import com.google.gson.JsonParser
apply plugin: 'launch4j'
apply plugin: 'me.tatarka.retrolambda'
@@ -47,19 +49,34 @@ if (!hasProperty('mainClass')) {
}
def readBuildNumber() {
def versionPropsFile = file('version.properties')
def versionPropsFile = file('version.properties')
def Properties versionProps = new Properties()
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger()
return code.toString()
} else {
versionPropsFile.createNewFile()
def code = versionProps['VERSION_CODE'].toInteger() + 1
versionProps['VERSION_CODE'] = code.toString()
versionProps.store(versionPropsFile.newWriter(), null)
return code.toString()
}
return "233"
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")
@@ -68,9 +85,9 @@ if (buildnumber == null)
if (buildnumber == null)
buildnumber = readBuildNumber()
def versionroot = System.getenv("VERSION_ROOT")
def versionroot = System.getenv("HMCL_VERSION_ROOT")
if (versionroot == null)
versionroot = "2.5.0"
versionroot = "2.5.3"
String mavenGroupId = 'HMCL'
String mavenVersion = versionroot + '.' + buildnumber
@@ -169,7 +186,7 @@ launch4j {
icon = new File(project.buildDir, '../icon.ico').absolutePath
version = mavenVersion
downloadUrl = 'http://java.com/download'
copyright = "Copyright(c) 2013-2015 HMCLSoft."
copyright = "Copyright(c) 2013-2016 HMCLSoft."
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
@@ -182,6 +199,7 @@ processResources {
}
}
build.dependsOn cleanVersionFile
build.dependsOn makeExecutable
build.dependsOn makePackGZ
build.dependsOn macAppCompressed
@@ -112,14 +112,16 @@ public class DynamicDownloadProvider extends MojangDownloadProvider {
@Override
public String getParsedDownloadURL(String str) {
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(launcherMetaAddr)) {
str = str.replace("https://launcher.mojang.com", launcherAddr);
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);
}
@@ -142,8 +144,7 @@ public class DynamicDownloadProvider extends MojangDownloadProvider {
try {
String providerInfo = NetUtils.get(PROVIDER_ADDR);
Map<String, String> addrInfo = null;
addrInfo = C.GSON.fromJson(providerInfo, new TypeToken<Map<String, String>>() {
}.getType());
addrInfo = C.GSON.fromJson(providerInfo, new TypeToken<Map<String, String>>() {}.getType());
if (addrInfo != null) {
setLibrariesAddr(getValue(addrInfo, "libraries"));
setAssetsAddr(getValue(addrInfo, "assets"));
@@ -151,7 +152,7 @@ public class DynamicDownloadProvider extends MojangDownloadProvider {
setLauncherAddr(getValue(addrInfo, "launcher"));
setVersionManifestAddr(getValue(addrInfo, "versionManifest"));
}
} catch (IOException ex) {
} catch (Throwable t) {
}
}
@@ -85,7 +85,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
return str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
else if (str.contains("typesafe") || str.contains("scala"))
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
return str.replace("http://files.minecraftforge.net/maven", "http://maven.oschina.net/content/groups/public");
return str.replace("http://files.minecraftforge.net/maven", "http://maven.aliyun.com/nexus/content/groups/public");
else
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
else
@@ -31,122 +31,122 @@ import org.jackhuang.hellominecraft.util.StrUtils;
*/
public class MinecraftLibrary extends IMinecraftLibrary {
@SerializedName("rules")
public ArrayList<Rules> rules;
@SerializedName("url")
public String url;
@SerializedName("natives")
public Natives natives;
@SerializedName("extract")
public Extract extract;
@SerializedName("downloads")
public LibrariesDownloadInfo downloads;
@SerializedName("rules")
public ArrayList<Rules> rules;
@SerializedName("url")
public String url;
@SerializedName("natives")
public Natives natives;
@SerializedName("extract")
public Extract extract;
@SerializedName("downloads")
public LibrariesDownloadInfo downloads;
public MinecraftLibrary(String name) {
super(name);
}
public MinecraftLibrary(String name) {
super(name);
}
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
super(name);
this.rules = (rules == null) ? null : (ArrayList<Rules>) rules.clone();
this.url = url;
this.natives = (natives == null) ? null : (Natives) natives.clone();
this.extract = (extract == null) ? null : (Extract) extract.clone();
}
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
super(name);
this.rules = (rules == null) ? null : (ArrayList<Rules>) rules.clone();
this.url = url;
this.natives = (natives == null) ? null : (Natives) natives.clone();
this.extract = (extract == null) ? null : (Extract) extract.clone();
}
@Override
public boolean allow() {
if (rules != null) {
boolean flag = false;
for (Rules r : rules) {
if ("disallow".equals(r.action()))
return false;
else if ("allow".equals(r.action()))
flag = true;
}
return flag;
}
return true;
}
private String formatArch(String nati) {
return nati == null ? "" : nati.replace("${arch}", Platform.getPlatform().getBit());
}
private String getNative() {
switch (OS.os()) {
case WINDOWS:
return formatArch(natives.windows);
case OSX:
return formatArch(natives.osx);
default:
return formatArch(natives.linux);
}
}
@Override
public boolean isRequiredToUnzip() {
return natives != null && allow();
}
public String formatName() {
String[] s = name.split(":");
if (s.length < 3) {
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();
}
@Override
public File getFilePath(File gameDir) {
LibraryDownloadInfo info = getDownloadInfo();
if (info == null) {
return null;
}
return new File(gameDir, "libraries/" + info.path);
}
@Override
public Extract getDecompressExtractRules() {
return extract == null ? new Extract() : extract;
}
public LibraryDownloadInfo getDownloadInfo() {
if (downloads == null) {
downloads = new LibrariesDownloadInfo();
}
LibraryDownloadInfo info = null;
if (natives != null) {
if (downloads.classifiers == null) {
downloads.classifiers = new HashMap<>();
} else {
if (!downloads.classifiers.containsKey(getNative())) {
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
} else {
info = downloads.classifiers.get(getNative());
@Override
public boolean allow() {
if (rules != null) {
boolean flag = false;
for (Rules r : rules) {
if ("disallow".equals(r.action())) {
return false;
} else if ("allow".equals(r.action())) {
flag = true;
}
}
} else if (downloads.artifact == null) {
downloads.artifact = info = new LibraryDownloadInfo();
} else {
info = downloads.artifact;
return flag;
}
if (StrUtils.isBlank(info.path)) {
info.path = formatName();
if (info.path == null) {
return null;
return true;
}
private String formatArch(String nati) {
return nati == null ? "" : nati.replace("${arch}", Platform.getPlatform().getBit());
}
private String getNative() {
switch (OS.os()) {
case WINDOWS:
return formatArch(natives.windows);
case OSX:
return formatArch(natives.osx);
default:
return formatArch(natives.linux);
}
}
@Override
public boolean isRequiredToUnzip() {
return natives != null && allow();
}
public String formatName() {
String[] s = name.split(":");
if (s.length < 3) {
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();
}
@Override
public File getFilePath(File gameDir) {
LibraryDownloadInfo info = getDownloadInfo();
if (info == null) {
return null;
}
return new File(gameDir, "libraries/" + info.path);
}
@Override
public Extract getDecompressExtractRules() {
return extract == null ? new Extract() : extract;
}
public LibraryDownloadInfo getDownloadInfo() {
if (downloads == null) {
downloads = new LibrariesDownloadInfo();
}
LibraryDownloadInfo info = null;
if (natives != null) {
if (downloads.classifiers == null) {
downloads.classifiers = new HashMap<>();
}
}
info.forgeURL = this.url;
return info;
}
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.
@@ -21,8 +21,10 @@ import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
@@ -67,7 +69,7 @@ public final class Config implements Cloneable {
private String localization;
@SerializedName("logintype")
private int logintype;
@SerializedName("downloadtype")
@SerializedName("downloadSourcetype")
private int downloadtype;
@SerializedName("configurations")
private TreeMap<String, Profile> configurations;
@@ -76,6 +78,16 @@ public final class Config implements Cloneable {
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() {
return java == null ? java = new ArrayList<>() : java;
@@ -27,7 +27,7 @@
<Group type="102" alignment="0" attributes="0">
<Component id="btnCheckUpdate" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
<Component id="btnHomepage" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
</Group>
@@ -127,7 +127,7 @@
<Group type="103" groupAlignment="3" 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="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnHomepage" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="lblRestart" min="-2" max="-2" attributes="0"/>
@@ -345,13 +345,15 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnMCBBS">
<Component class="javax.swing.JButton" name="btnHomepage">
<Properties>
<Property name="text" type="java.lang.String" value="MCBBS"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="launcher.homepage" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnHomepageActionPerformed"/>
</Events>
</Component>
</SubComponents>
@@ -116,7 +116,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
cboLang = new javax.swing.JComboBox();
lblLang = new javax.swing.JLabel();
lblRestart = new javax.swing.JLabel();
btnMCBBS = new javax.swing.JButton();
btnHomepage = new javax.swing.JButton();
cboDownloadSource.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
@@ -236,11 +236,11 @@ public class LauncherSettingsPanel extends AnimatedPanel {
lblRestart.setText(C.i18n("launcher.restart")); // NOI18N
btnMCBBS.setText("MCBBS");
btnMCBBS.setToolTipText("");
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
btnHomepage.setText(C.i18n("launcher.homepage")); // NOI18N
btnHomepage.setToolTipText("");
btnHomepage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCBBSActionPerformed(evt);
btnHomepageActionPerformed(evt);
}
});
@@ -258,7 +258,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
.addGroup(layout.createSequentialGroup()
.addComponent(btnCheckUpdate)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCBBS)
.addComponent(btnHomepage)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkDecorated))
.addGroup(layout.createSequentialGroup()
@@ -341,7 +341,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(chkDecorated)
.addComponent(btnMCBBS))
.addComponent(btnHomepage))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblRestart)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 116, Short.MAX_VALUE)
@@ -429,13 +429,13 @@ public class LauncherSettingsPanel extends AnimatedPanel {
Settings.getInstance().setProxyPassword(txtProxyPassword.getText());
}//GEN-LAST:event_txtProxyPasswordFocusLost
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
private void btnHomepageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnHomepageActionPerformed
SwingUtils.openLink(C.URL_PUBLISH);
}//GEN-LAST:event_btnMCBBSActionPerformed
}//GEN-LAST:event_btnHomepageActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCheckUpdate;
private javax.swing.JButton btnMCBBS;
private javax.swing.JButton btnHomepage;
private javax.swing.JButton btnSelBackgroundPath;
private javax.swing.JComboBox cboDownloadSource;
private javax.swing.JComboBox cboLang;
@@ -19,7 +19,6 @@ package org.jackhuang.hellominecraft.launcher.ui;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -36,9 +35,13 @@ 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.util.C;
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;
/**
@@ -49,12 +52,21 @@ 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 ScheduledExecutorService scheduledexec = Executors.newScheduledThreadPool(1);
public final ScheduledExecutorService scheduledexec = Executors.newScheduledThreadPool(1);
public RecommendPanel() {
initComponents();
recommends = new ArrayList<RecommendInfo>();
new LoadImages().execute();
setCursor(new Cursor(Cursor.HAND_CURSOR));
@@ -67,12 +79,42 @@ public class RecommendPanel extends JPanel {
});
}
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 (info.link != null && !info.link.equals("")) {
if (StrUtils.isNotBlank(info.link)) {
if (info.once) {
ignoreTheRecommend(info.url);
}
SwingUtils.openLink(info.link);
}
}
@@ -86,13 +128,14 @@ public class RecommendPanel extends JPanel {
@Override
public void run() {
for (RecommendInfo info : recommends) {
try {
File tempFile = File.createTempFile("hmcl", "png");
String tempPath = tempFile.getCanonicalPath();
if (NetUtils.download(info.url, tempPath)) {
info.image = ImageIO.read(tempFile);
}
} catch (IOException ex) {
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) { }
}
}
@@ -105,9 +148,13 @@ public class RecommendPanel extends JPanel {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int showIndex = getNextImageIndex();
RecommendInfo info = recommends.get(showIndex);
RecommendPanel.this.setImage(info.url, info.image);
synchronized(RecommendPanel.class) {
if (ignoreSwitch) {
ignoreSwitch = false;
} else {
showNext();
}
}
}
});
}
@@ -142,25 +189,49 @@ public class RecommendPanel extends JPanel {
}
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) {
showIndex = getNextImageIndex(++showIndex);
if (info.image == null || ignoreShowUrl(info.url)) {
showIndex = getNextImageIndex(++showIndex);
}
return showIndex;
}
public int getNextImageIndex() {
int showIndex = 0;
if (imageKey != null) {
showIndex = getCurrentImageIndex();
showIndex++;
}
if (showIndex >= recommends.size()) {
int showIndex = getCurrentImageIndex();
if (++showIndex >= recommends.size()) {
showIndex = 0;
}
showIndex = getNextImageIndex(showIndex);
@@ -171,43 +242,49 @@ public class RecommendPanel extends JPanel {
int currIndex = 0;
for (int i = 0; i < recommends.size(); i++) {
RecommendInfo info = recommends.get(i);
if (imageKey != null && info.url.equals(imageKey)) {
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;
//setToolTipText(C.i18n("ui.message.recommend_tip"));
setSize(image.getWidth(this), image.getHeight(this));
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 (null == currImage) {
return;
if (currImage != null) {
g.drawImage(currImage, 0, 0, currImage.getWidth(this), currImage.getHeight(this), this);
}
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, String>>, Void> {
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, String>> doInBackground() throws Exception {
List<Map<String, String>> infos = null;
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("")) {
@@ -215,13 +292,12 @@ public class RecommendPanel extends JPanel {
}
Map<String, Object> data = new Gson().fromJson(content,
new TypeToken<Map<String, Object>>() {
}.getType());
new TypeToken<Map<String, Object>>() {}.getType());
if (data == null) {
break;
}
infos = (List<Map<String, String>>) data.get("data");
infos = (List<Map<String, Object>>) data.get("data");
} while (false);
return infos;
}
@@ -229,14 +305,27 @@ public class RecommendPanel extends JPanel {
@Override
protected void done() {
try {
List<Map<String, String>> infos = this.get();
List<Map<String, Object>> infos = this.get();
if (infos == null) {
return;
}
for (Map<String, String> info : infos) {
for (Map<String, Object> info : infos) {
RecommendInfo recommend = new RecommendInfo();
recommend.url = info.get("url");
recommend.link = info.get("link");
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);
}
@@ -138,9 +138,9 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
HashMap<String, String> map = new HashMap<>();
map.put("CrashReport", text);
try {
NetUtils.post(NetUtils.constantURL("http://huangyuhui.duapp.com/crash.php"), map);
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Failed to post HMCL server.", ex);
NetUtils.post(NetUtils.constantURL("http://client.api.mcgogogo.com:81/crash_report.php"), map);
} catch (Throwable error) {
LOGGER.log(Level.SEVERE, "Failed to post HMCL server.", error);
}
});
t.setDaemon(true);
@@ -17,6 +17,7 @@
*/
package org.jackhuang.hellominecraft.launcher.util.upgrade;
import java.awt.Dimension;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -36,16 +37,21 @@ import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
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.logging.HMCLog;
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.TaskWindow;
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.util.ArrayUtils;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.UpdateChecker;
import org.jackhuang.hellominecraft.util.Utils;
import org.jackhuang.hellominecraft.util.VersionNumber;
@@ -54,6 +60,7 @@ import org.jackhuang.hellominecraft.util.system.FileUtils;
import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.system.OS;
import org.jackhuang.hellominecraft.util.tasks.TaskList;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
/**
*
@@ -111,12 +118,38 @@ public class AppDataUpgrader extends IUpgrader {
versionNumber.firstVer + "." + versionNumber.secondVer + "." +
versionNumber.thirdVer + "\n" +
C.i18n("update.should_open_link");
JCheckBox checkbox = new JCheckBox(C.i18n("update.ignore"));
int ret = MessageBox.Show(new Object[]{content, checkbox}, MessageBox.YES_NO_OPTION);
if (ret == MessageBox.NO_OPTION) {
Settings.getInstance().setIgnoreUpdate(versionNumber);
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;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

-2
View File
@@ -1,2 +0,0 @@
#Thu Jul 07 14:30:49 CST 2016
VERSION_CODE=92
@@ -29,10 +29,10 @@ public final class C {
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
//http://repo1.maven.org/maven2
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_PUBLISH = "http://www.hmclsoft.com";
public static final String URL_GITHUB = "https://github.com/mclauncher/HMCL/issues";
public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher";
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";
@@ -26,12 +26,26 @@ import java.util.Map;
public interface IUpdateChecker {
/**
*
* Update response
*/
void checkOutdate();
/**
*
* @return Update log
*/
String getUpdateLog();
/**
*
* @return Server to assign a mandatory update
*/
boolean isForceUpdate();
/**
*
* @return User manual update
*/
boolean isManualUpdate();
/**
@@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import java.util.Map;
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
/**
*
@@ -34,9 +35,12 @@ public final class UpdateChecker implements IUpdateChecker {
public String versionString;
public VersionNumber base;
private VersionNumber value;
private boolean isforceUpdate = false;
private boolean isManualUpdate = false;
private String updateLog = null;
public String type;
private Map<String, String> download_link = null;
@@ -53,12 +57,17 @@ public final class UpdateChecker implements IUpdateChecker {
isManualUpdate = showMessage;
if (value == null) {
versionString = NetUtils.get(VERSION_URL + type + "&ver=" + base.toString());
versionString = NetUtils.get(VERSION_URL + type +
"&ver=" + base.toString() +
"&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"));
value = VersionNumber.check((String) versionInfo.get("version"));
if (versionInfo.containsKey("force"))
isforceUpdate = (boolean)versionInfo.get("force");
isforceUpdate = (boolean) versionInfo.get("force");
if (versionInfo.containsKey("log"))
updateLog = (String) versionInfo.get("log");
}
if (value == null) {
@@ -92,6 +101,11 @@ public final class UpdateChecker implements IUpdateChecker {
return isManualUpdate;
}
@Override
public String getUpdateLog() {
return updateLog;
}
@Override
public synchronized OverridableSwingWorker<Map<String, String>> requestDownloadLink() {
return new OverridableSwingWorker() {
@@ -36,7 +36,7 @@
<Group type="102" alignment="1" attributes="0">
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
<Component id="btnHomepage" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCF" min="-2" 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="btnClose" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnHomepage" 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="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
@@ -117,12 +117,14 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnMCBBS">
<Component class="javax.swing.JButton" name="btnHomepage">
<Properties>
<Property name="text" type="java.lang.String" value="MCBBS"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="logwindow.homepage" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnHomepageActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnTieBa">
@@ -69,7 +69,7 @@ public class LogWindow extends javax.swing.JFrame {
btnClose = new javax.swing.JButton();
btnCopy = new javax.swing.JButton();
lblCrash = new javax.swing.JLabel();
btnMCBBS = new javax.swing.JButton();
btnHomepage = new javax.swing.JButton();
btnTieBa = new javax.swing.JButton();
btnMCF = 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
btnMCBBS.setText("MCBBS");
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
btnHomepage.setText(C.i18n("logwindow.homepage")); // NOI18N
btnHomepage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCBBSActionPerformed(evt);
btnHomepageActionPerformed(evt);
}
});
@@ -156,7 +156,7 @@ public class LogWindow extends javax.swing.JFrame {
.addGroup(layout.createSequentialGroup()
.addComponent(btnTieBa)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCBBS)
.addComponent(btnHomepage)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCF)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -184,7 +184,7 @@ public class LogWindow extends javax.swing.JFrame {
.addComponent(btnClear)
.addComponent(btnClose)
.addComponent(btnCopy)
.addComponent(btnMCBBS)
.addComponent(btnHomepage)
.addComponent(btnTieBa)
.addComponent(btnMCF)
.addComponent(btnTerminateGame)
@@ -209,9 +209,9 @@ public class LogWindow extends javax.swing.JFrame {
Utils.setClipborad(this.txtLog.getText());
}//GEN-LAST:event_btnCopyActionPerformed
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
private void btnHomepageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnHomepageActionPerformed
SwingUtils.openLink(C.URL_PUBLISH);
}//GEN-LAST:event_btnMCBBSActionPerformed
}//GEN-LAST:event_btnHomepageActionPerformed
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
SwingUtils.openLink(C.URL_TIEBA);
@@ -284,7 +284,7 @@ public class LogWindow extends javax.swing.JFrame {
@Override
public void setVisible(boolean b) {
lblCrash.setVisible(false);
btnMCBBS.setVisible(false);
btnHomepage.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
super.setVisible(b);
@@ -293,13 +293,13 @@ public class LogWindow extends javax.swing.JFrame {
public void showAsCrashWindow(boolean out_date) {
if (out_date) {
lblCrash.setVisible(false);
btnMCBBS.setVisible(false);
btnHomepage.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
} else {
lblCrash.setVisible(true);
btnMCBBS.setVisible(true);
btnHomepage.setVisible(true);
btnTieBa.setVisible(true);
btnMCF.setVisible(true);
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 btnCopy;
private javax.swing.JButton btnGitHub;
private javax.swing.JButton btnMCBBS;
private javax.swing.JButton btnHomepage;
private javax.swing.JButton btnMCF;
private javax.swing.JButton btnTerminateGame;
private javax.swing.JButton btnTieBa;
@@ -301,6 +301,7 @@ 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.download_source=下载源
launcher.homepage=官网
launcher.background_location=背景地址
launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。
launcher.versions_json_not_matched=版本%s格式不规范!该版本文件夹下有json:%s,是否更名这个文件来规范格式?
@@ -375,6 +376,7 @@ update.ignore=不再提醒此版本更新
logwindow.terminate_game=结束游戏进程
logwindow.tieba=贴吧
logwindow.title=日志
logwindow.homepage=官网
selector.choose=选择
@@ -301,6 +301,7 @@ mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u54
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.download_source=\u4e0b\u8f7d\u6e90
launcher.homepage=\u5b98\u7f51
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.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
@@ -375,6 +376,7 @@ update.ignore=\u4e0d\u518d\u63d0\u9192\u6b64\u7248\u672c\u66f4\u65b0
logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b
logwindow.tieba=\u8d34\u5427
logwindow.title=\u65e5\u5fd7
logwindow.homepage=\u5b98\u7f51
selector.choose=\u9009\u62e9
@@ -301,6 +301,7 @@ 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.download_source=Download Source
launcher.homepage=Homepage
launcher.background_location=Background Location
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?
@@ -375,6 +376,7 @@ update.ignore=Do not remind this version update.
logwindow.terminate_game=Terminate Game
logwindow.tieba=Baidu Tieba
logwindow.title=Log
logwindow.homepage=Homepage
selector.choose=Choose
@@ -301,6 +301,7 @@ 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.download_source=Download Source
launcher.homepage=Homepage
launcher.background_location=Background Location
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?
@@ -375,6 +376,7 @@ update.ignore=Do not remind this version update.
logwindow.terminate_game=Terminate Game
logwindow.tieba=Baidu Tieba
logwindow.title=Log
logwindow.homepage=Homepage
selector.choose=Choose
@@ -301,6 +301,7 @@ 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.download_source=下載源
launcher.homepage=官網
launcher.background_location=背景地址
launcher.exit_failed=強制退出失敗,可能是Forge 1.7.10及更高版本導致的,無法解決。
launcher.versions_json_not_matched=版本%s格式不規範!該版本資料夾下有json:%s,是否更名這個資料來規範格式?
@@ -375,6 +376,7 @@ update.ignore=不再提醒此版本更新
logwindow.terminate_game=結束遊戲進程
logwindow.tieba=貼吧
logwindow.title=日志
logwindow.homepage=官網
selector.choose=選擇
@@ -301,6 +301,7 @@ mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u54
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.download_source=\u4e0b\u8f09\u6e90
launcher.homepage=\u5b98\u7db2
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.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
@@ -375,6 +376,7 @@ update.ignore=\u4e0d\u518d\u63d0\u9192\u6b64\u7248\u672c\u66f4\u65b0
logwindow.terminate_game=\u7d50\u675f\u904a\u6232\u9032\u7a0b
logwindow.tieba=\u8cbc\u5427
logwindow.title=\u65e5\u5fd7
logwindow.homepage=\u5b98\u7db2
selector.choose=\u9078\u64c7