Prepare for proguard

This commit is contained in:
huangyuhui
2017-08-27 12:49:56 +08:00
parent b07144278b
commit 8c61bc1a5e
16 changed files with 97 additions and 36 deletions

View File

@@ -2,6 +2,7 @@ import java.security.MessageDigest
import java.util.jar.JarFile import java.util.jar.JarFile
import java.util.jar.Pack200 import java.util.jar.Pack200
import java.util.zip.GZIPOutputStream import java.util.zip.GZIPOutputStream
import java.io.File
if (!hasProperty('mainClass')) { if (!hasProperty('mainClass')) {
ext.mainClass = 'org.jackhuang.hmcl.Main' ext.mainClass = 'org.jackhuang.hmcl.Main'
@@ -48,7 +49,8 @@ jar {
manifest { manifest {
attributes 'Created-By' : 'Copyright(c) 2013-2017 huangyuhui.', attributes 'Created-By' : 'Copyright(c) 2013-2017 huangyuhui.',
'Main-Class' : mainClass 'Main-Class' : mainClass,
'Multi-Release': "true"
} }
doLast { doLast {
@@ -78,7 +80,7 @@ task makeExecutable(dependsOn: jar) doLast {
ext { ext {
jar.classifier = '' jar.classifier = ''
makeExecutableinjar = jar.archivePath makeExecutableinjar = jar.archivePath
jar.classifier = '' jar.classifier = 'optimized'
makeExecutableoutjar = jar.archivePath makeExecutableoutjar = jar.archivePath
jar.classifier = '' jar.classifier = ''
} }
@@ -90,7 +92,7 @@ task makeExecutable(dependsOn: jar) doLast {
while((read = is.read(bytes)) != -1) while((read = is.read(bytes)) != -1)
fos.write(bytes, 0, read); fos.write(bytes, 0, read);
is.close() is.close()
is = new FileInputStream(makeExecutableinjar) is = new FileInputStream(makeExecutableoutjar)
while((read = is.read(bytes)) != -1) while((read = is.read(bytes)) != -1)
fos.write(bytes, 0, read); fos.write(bytes, 0, read);
is.close() is.close()
@@ -121,6 +123,42 @@ task makePackGZ(dependsOn: jar) doLast {
fileEx.append sha1Hex fileEx.append sha1Hex
} }
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
ext {
def re = jar.classifier
injar = jar.archivePath
jar.classifier = 'optimized'
outjar = jar.archivePath
jar.classifier = re
}
injars(/*["filter": "!META-INF/**,**"], */injar)
String javaHome = System.getProperty("java.home")
if (!javaHome.endsWith("jre"))
javaHome += File.separator + "jre"
libraryjars javaHome + "/lib/rt.jar"
libraryjars javaHome + "/lib/jce.jar"
libraryjars javaHome + "/lib/jsse.jar"
libraryjars javaHome + "/lib/ext/jfxrt.jar"
outjars outjar
configuration 'proguard.pro'
}
task combineMETA_INF(type: Jar) {
ext {
def re = jar.classifier
injar = jar.archivePath
jar.classifier = 'optimized'
outjar = jar.archivePath
jar.classifier = re
}
from zipTree(outjar)
from zipTree(injar).matching {
include "META-INF/"
}
}
build.dependsOn makeExecutable build.dependsOn makeExecutable
//build.dependsOn makePackGZ //build.dependsOn makePackGZ
//Kotlin classes will be ignored by Pack200 due to class unrecognized attribute //Kotlin classes will be ignored by Pack200 due to class unrecognized attribute

15
HMCL/proguard.pro vendored Normal file
View File

@@ -0,0 +1,15 @@
-target 1.8
-dontoptimize
-dontobfuscate
# JFoenix
-keep class com.jfoenix.** {
<fields>;
<methods>;
}
# HMCL
-keep class org.jackhuang.** {
<fields>;
<methods>;
}

View File

@@ -42,19 +42,15 @@ fun i18n(key: String): String {
class Main : Application() { class Main : Application() {
override fun start(stage: Stage) { override fun start(stage: Stage) {
println(System.currentTimeMillis())
// When launcher visibility is set to "hide and reopen" without [Platform.implicitExit] = false, // When launcher visibility is set to "hide and reopen" without [Platform.implicitExit] = false,
// Stage.show() cannot work again because JavaFX Toolkit have already shut down. // Stage.show() cannot work again because JavaFX Toolkit have already shut down.
Platform.setImplicitExit(false) Platform.setImplicitExit(false)
Controllers.initialize(stage) Controllers.initialize(stage)
println("Showing stage: " + System.currentTimeMillis())
stage.isResizable = false stage.isResizable = false
stage.scene = Controllers.scene stage.scene = Controllers.scene
stage.show() stage.show()
println("Showed stage: " + System.currentTimeMillis())
} }
companion object { companion object {

View File

@@ -47,7 +47,6 @@ object LauncherHelper {
val account = Settings.selectedAccount ?: throw IllegalStateException("No account here") val account = Settings.selectedAccount ?: throw IllegalStateException("No account here")
val version = repository.getVersion(selectedVersion) val version = repository.getVersion(selectedVersion)
val setting = profile.getVersionSetting(selectedVersion) val setting = profile.getVersionSetting(selectedVersion)
var finished = 0
Controllers.dialog(launchingStepsPane) Controllers.dialog(launchingStepsPane)
task(Scheduler.JAVAFX) { emitStatus(LoadingState.DEPENDENCIES) } task(Scheduler.JAVAFX) { emitStatus(LoadingState.DEPENDENCIES) }
@@ -86,13 +85,15 @@ object LauncherHelper {
.executor() .executor()
.apply { .apply {
taskListener = object : TaskListener { taskListener = object : TaskListener {
var finished = 0
override fun onFinished(task: Task) { override fun onFinished(task: Task) {
++finished ++finished
runOnUiThread { launchingStepsPane.pgsTasks.progress = 1.0 * finished / totTask.get() } runOnUiThread { launchingStepsPane.pgsTasks.progress = 1.0 * finished / totTask.get() }
} }
override fun onTerminate() { override fun onTerminate() {
runOnUiThread { Controllers.closeDialog() } runOnUiThread(Controllers::closeDialog)
} }
} }
}.start() }.start()

View File

@@ -48,7 +48,7 @@ class Profile(name: String = "Default", initialGameDir: File = File(".minecraft"
init { init {
gameDirProperty.onChange { repository.changeDirectory(it!!) } gameDirProperty.onChange { repository.changeDirectory(it!!) }
selectedVersionProperty.addListener { _ -> verifySelectedVersion() } selectedVersionProperty.onInvalidated(this::verifySelectedVersion)
EVENT_BUS.channel<RefreshedVersionsEvent>() += { event -> if (event.source == repository) verifySelectedVersion() } EVENT_BUS.channel<RefreshedVersionsEvent>() += { event -> if (event.source == repository) verifySelectedVersion() }
} }

View File

@@ -55,7 +55,7 @@ fun Node.loadFXML(absolutePath: String) {
} }
fun ListView<*>.smoothScrolling() { fun ListView<*>.smoothScrolling() {
skinProperty().addListener { _ -> skinProperty().onInvalidated {
val bar = lookup(".scroll-bar") as ScrollBar val bar = lookup(".scroll-bar") as ScrollBar
val virtualFlow = lookup(".virtual-flow") val virtualFlow = lookup(".virtual-flow")
val frictions = doubleArrayOf(0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005, 0.00003, 0.00001) val frictions = doubleArrayOf(0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005, 0.00003, 0.00001)
@@ -85,7 +85,7 @@ fun ListView<*>.smoothScrolling() {
for (i in derivatives.indices) { for (i in derivatives.indices) {
derivatives[i] *= frictions[i] derivatives[i] *= frictions[i]
} }
for (i in 1..derivatives.size - 1) { for (i in 1 until derivatives.size) {
derivatives[i] += derivatives[i - 1] derivatives[i] += derivatives[i - 1]
} }
val dy = derivatives[derivatives.size - 1] val dy = derivatives[derivatives.size - 1]
@@ -243,12 +243,12 @@ fun Node.installTooltip(openDelay: Double = 1000.0, visibleDelay: Double = 5000.
} }
fun JFXTextField.setValidateWhileTextChanged() { fun JFXTextField.setValidateWhileTextChanged() {
textProperty().addListener { _ -> validate() } textProperty().onInvalidated(this::validate)
validate() validate()
} }
fun JFXPasswordField.setValidateWhileTextChanged() { fun JFXPasswordField.setValidateWhileTextChanged() {
textProperty().addListener { _ -> validate() } textProperty().onInvalidated(this::validate)
validate() validate()
} }

View File

@@ -89,7 +89,7 @@ class LeftPaneController(private val leftPane: AdvancedListBox) {
profilePane.children profilePane.children
.filter { it is RipplerContainer && it.properties["profile"] is Pair<*, *> } .filter { it is RipplerContainer && it.properties["profile"] is Pair<*, *> }
.forEach { (it as RipplerContainer).selected = (it.properties["profile"] as Pair<String, VersionListItem>).first == profile.name } .forEach { (it as RipplerContainer).selected = (it.properties["profile"] as Pair<*, *>).first == profile.name }
} }
fun onProfilesLoading() { fun onProfilesLoading() {

View File

@@ -121,14 +121,14 @@ class LogWindow : Stage() {
btnInfos.textProperty().bind(Bindings.createStringBinding(Callable { infoProperty.get().toString() + " infos" }, infoProperty)) btnInfos.textProperty().bind(Bindings.createStringBinding(Callable { infoProperty.get().toString() + " infos" }, infoProperty))
btnDebugs.textProperty().bind(Bindings.createStringBinding(Callable { debugProperty.get().toString() + " debugs" }, debugProperty)) btnDebugs.textProperty().bind(Bindings.createStringBinding(Callable { debugProperty.get().toString() + " debugs" }, debugProperty))
btnFatals.selectedProperty().addListener(this::specificChanged) btnFatals.selectedProperty().onInvalidated(this::specificChanged)
btnErrors.selectedProperty().addListener(this::specificChanged) btnErrors.selectedProperty().onInvalidated(this::specificChanged)
btnWarns.selectedProperty().addListener(this::specificChanged) btnWarns.selectedProperty().onInvalidated(this::specificChanged)
btnInfos.selectedProperty().addListener(this::specificChanged) btnInfos.selectedProperty().onInvalidated(this::specificChanged)
btnDebugs.selectedProperty().addListener(this::specificChanged) btnDebugs.selectedProperty().onInvalidated(this::specificChanged)
} }
private fun specificChanged(observable: Observable) { private fun specificChanged() {
var res = "" var res = ""
if (btnFatals.isSelected) res += "\"fatal\", " if (btnFatals.isSelected) res += "\"fatal\", "
if (btnErrors.isSelected) res += "\"error\", " if (btnErrors.isSelected) res += "\"error\", "

View File

@@ -101,7 +101,7 @@ class MainPage : StackPane(), DecoratorPage {
fun onProfileChanged(event: ProfileChangedEvent) = runOnUiThread { fun onProfileChanged(event: ProfileChangedEvent) = runOnUiThread {
val profile = event.value val profile = event.value
profile.selectedVersionProperty.setChangedListener { t -> profile.selectedVersionProperty.setChangedListener {
versionChanged(profile.selectedVersion) versionChanged(profile.selectedVersion)
} }
loadVersions(profile) loadVersions(profile)

View File

@@ -35,6 +35,7 @@ import javafx.scene.paint.Paint
import javafx.scene.shape.Rectangle import javafx.scene.shape.Rectangle
import org.jackhuang.hmcl.util.getValue import org.jackhuang.hmcl.util.getValue
import org.jackhuang.hmcl.util.onChange import org.jackhuang.hmcl.util.onChange
import org.jackhuang.hmcl.util.onInvalidated
import org.jackhuang.hmcl.util.setValue import org.jackhuang.hmcl.util.setValue
import java.util.concurrent.Callable import java.util.concurrent.Callable
@@ -106,7 +107,7 @@ open class RipplerContainer(@NamedArg("container") container: Node): StackPane()
} }
} }
pressedProperty().addListener { _ -> this.buttonRippler.hideOverlay() } pressedProperty().onInvalidated(this.buttonRippler::hideOverlay)
isPickOnBounds = false isPickOnBounds = false
this.buttonContainer.isPickOnBounds = false this.buttonContainer.isPickOnBounds = false
this.buttonContainer.shapeProperty().bind(shapeProperty()) this.buttonContainer.shapeProperty().bind(shapeProperty())
@@ -136,8 +137,8 @@ open class RipplerContainer(@NamedArg("container") container: Node): StackPane()
this.updateChildren() this.updateChildren()
containerProperty.addListener { _ -> updateChildren() } containerProperty.onInvalidated(this::updateChildren)
selectedProperty.addListener { _ -> selectedProperty.onInvalidated {
if (selected) background = Background(BackgroundFill(ripplerFill, defaultRadii, null)) if (selected) background = Background(BackgroundFill(ripplerFill, defaultRadii, null))
else background = Background(BackgroundFill(Color.TRANSPARENT, defaultRadii, null)) else background = Background(BackgroundFill(Color.TRANSPARENT, defaultRadii, null))
} }

View File

@@ -31,6 +31,7 @@ import org.jackhuang.hmcl.ui.construct.Validator
import org.jackhuang.hmcl.ui.loadFXML import org.jackhuang.hmcl.ui.loadFXML
import org.jackhuang.hmcl.ui.wizard.WizardController import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage import org.jackhuang.hmcl.ui.wizard.WizardPage
import org.jackhuang.hmcl.util.onInvalidated
class InstallersPage(private val controller: WizardController, private val repository: GameRepository, private val downloadProvider: DownloadProvider): StackPane(), WizardPage { class InstallersPage(private val controller: WizardController, private val repository: GameRepository, private val downloadProvider: DownloadProvider): StackPane(), WizardPage {
@@ -50,9 +51,7 @@ class InstallersPage(private val controller: WizardController, private val repos
val gameVersion = controller.settings["game"] as String val gameVersion = controller.settings["game"] as String
txtName.validators += Validator { !repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") } txtName.validators += Validator { !repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") }
txtName.textProperty().addListener { _ -> txtName.textProperty().onInvalidated { btnInstall.isDisable = !txtName.validate() }
btnInstall.isDisable = !txtName.validate()
}
txtName.text = gameVersion txtName.text = gameVersion
btnForge.setOnMouseClicked { btnForge.setOnMouseClicked {

View File

@@ -34,6 +34,7 @@ import org.jackhuang.hmcl.ui.*
import org.jackhuang.hmcl.ui.construct.Validator import org.jackhuang.hmcl.ui.construct.Validator
import org.jackhuang.hmcl.ui.wizard.WizardController import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage import org.jackhuang.hmcl.ui.wizard.WizardPage
import org.jackhuang.hmcl.util.onInvalidated
class ModpackPage(private val controller: WizardController): StackPane(), WizardPage { class ModpackPage(private val controller: WizardController): StackPane(), WizardPage {
override val title: String = i18n("modpack.task.install") override val title: String = i18n("modpack.task.install")
@@ -62,9 +63,7 @@ class ModpackPage(private val controller: WizardController): StackPane(), Wizard
controller.settings[MODPACK_FILE] = selectedFile controller.settings[MODPACK_FILE] = selectedFile
lblModpackLocation.text = selectedFile.absolutePath lblModpackLocation.text = selectedFile.absolutePath
txtModpackName.validators += Validator { !profile.repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") } txtModpackName.validators += Validator { !profile.repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") }
txtModpackName.textProperty().addListener { _ -> txtModpackName.textProperty().onInvalidated { btnInstall.isDisable = !txtModpackName.validate() }
btnInstall.isDisable = !txtModpackName.validate()
}
try { try {
manifest = readModpackManifest(selectedFile) manifest = readModpackManifest(selectedFile)

View File

@@ -34,6 +34,7 @@ import org.jackhuang.hmcl.ui.loadFXML
import org.jackhuang.hmcl.ui.smoothScrolling import org.jackhuang.hmcl.ui.smoothScrolling
import org.jackhuang.hmcl.ui.wizard.WizardController import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage import org.jackhuang.hmcl.ui.wizard.WizardPage
import org.jackhuang.hmcl.util.onInvalidated
class ModpackInfoPage(private val controller: WizardController, version: String): StackPane(), WizardPage { class ModpackInfoPage(private val controller: WizardController, version: String): StackPane(), WizardPage {
override val title: String = i18n("modpack.wizard.step.1.title") override val title: String = i18n("modpack.wizard.step.1.title")
@@ -50,14 +51,14 @@ class ModpackInfoPage(private val controller: WizardController, version: String)
loadFXML("/assets/fxml/modpack/info.fxml") loadFXML("/assets/fxml/modpack/info.fxml")
scroll.smoothScrolling() scroll.smoothScrolling()
txtModpackName.text = version txtModpackName.text = version
txtModpackName.textProperty().addListener { _ -> checkValidation() } txtModpackName.textProperty().onInvalidated(this::checkValidation)
txtModpackAuthor.textProperty().addListener { _ -> checkValidation() } txtModpackAuthor.textProperty().onInvalidated(this::checkValidation)
txtModpackVersion.textProperty().addListener { _ -> checkValidation() } txtModpackVersion.textProperty().onInvalidated(this::checkValidation)
txtModpackAuthor.text = Settings.selectedAccount?.username ?: "" txtModpackAuthor.text = Settings.selectedAccount?.username ?: ""
lblVersionName.text = version lblVersionName.text = version
} }
fun checkValidation() { private fun checkValidation() {
btnNext.isDisable = !txtModpackName.validate() || !txtModpackVersion.validate() || !txtModpackAuthor.validate() btnNext.isDisable = !txtModpackName.validate() || !txtModpackVersion.validate() || !txtModpackAuthor.validate()
} }

View File

@@ -74,7 +74,14 @@ internal class Log4jHandler(private val callback: (String, Log4jLevel) -> Unit)
*/ */
fun newLine(content: String) = fun newLine(content: String) =
Scheduler.COMPUTATION.schedule { Scheduler.COMPUTATION.schedule {
outputStream.write((content + OS.LINE_SEPARATOR).replace("log4j:Event", "log4j_Event").replace("log4j:Message", "log4j_Message").replace("log4j:Throwable", "log4j_Throwable").toByteArray()) var log = content
if (!log.trim().startsWith("<"))
log = "<![CDATA[" + log.replace("]]>", "") + "]]>"
outputStream.write((log + OS.LINE_SEPARATOR)
.replace("log4j:Event", "log4j_Event")
.replace("log4j:Message", "log4j_Message")
.replace("log4j:Throwable", "log4j_Throwable")
.toByteArray())
outputStream.flush() outputStream.flush()
} }

View File

@@ -32,3 +32,5 @@ fun ObservableDoubleValue.onChange(op: (Double) -> Unit) = apply { addListener {
fun <T> ObservableList<T>.onChange(op: (ListChangeListener.Change<out T>) -> Unit) = apply { fun <T> ObservableList<T>.onChange(op: (ListChangeListener.Change<out T>) -> Unit) = apply {
addListener(ListChangeListener { op(it) }) addListener(ListChangeListener { op(it) })
} }
fun <T> ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }

View File

@@ -27,6 +27,7 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'net.sf.proguard:proguard-gradle:5.3.3'
} }
} }
@@ -61,6 +62,7 @@ allprojects {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "com.google.code.gson:gson:2.8.1" compile "com.google.code.gson:gson:2.8.1"
compile "org.apache.commons:commons-compress:1.8.1" compile "org.apache.commons:commons-compress:1.8.1"
compile "org.tukaani:xz:1.6"
testCompile group: 'junit', name: 'junit', version: '4.12' testCompile group: 'junit', name: 'junit', version: '4.12'
} }