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.Pack200
import java.util.zip.GZIPOutputStream
import java.io.File
if (!hasProperty('mainClass')) {
ext.mainClass = 'org.jackhuang.hmcl.Main'
@@ -48,7 +49,8 @@ jar {
manifest {
attributes 'Created-By' : 'Copyright(c) 2013-2017 huangyuhui.',
'Main-Class' : mainClass
'Main-Class' : mainClass,
'Multi-Release': "true"
}
doLast {
@@ -78,7 +80,7 @@ task makeExecutable(dependsOn: jar) doLast {
ext {
jar.classifier = ''
makeExecutableinjar = jar.archivePath
jar.classifier = ''
jar.classifier = 'optimized'
makeExecutableoutjar = jar.archivePath
jar.classifier = ''
}
@@ -90,7 +92,7 @@ task makeExecutable(dependsOn: jar) doLast {
while((read = is.read(bytes)) != -1)
fos.write(bytes, 0, read);
is.close()
is = new FileInputStream(makeExecutableinjar)
is = new FileInputStream(makeExecutableoutjar)
while((read = is.read(bytes)) != -1)
fos.write(bytes, 0, read);
is.close()
@@ -121,6 +123,42 @@ task makePackGZ(dependsOn: jar) doLast {
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 makePackGZ
//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() {
override fun start(stage: Stage) {
println(System.currentTimeMillis())
// 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.
Platform.setImplicitExit(false)
Controllers.initialize(stage)
println("Showing stage: " + System.currentTimeMillis())
stage.isResizable = false
stage.scene = Controllers.scene
stage.show()
println("Showed stage: " + System.currentTimeMillis())
}
companion object {

View File

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

View File

@@ -48,7 +48,7 @@ class Profile(name: String = "Default", initialGameDir: File = File(".minecraft"
init {
gameDirProperty.onChange { repository.changeDirectory(it!!) }
selectedVersionProperty.addListener { _ -> verifySelectedVersion() }
selectedVersionProperty.onInvalidated(this::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() {
skinProperty().addListener { _ ->
skinProperty().onInvalidated {
val bar = lookup(".scroll-bar") as ScrollBar
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)
@@ -85,7 +85,7 @@ fun ListView<*>.smoothScrolling() {
for (i in derivatives.indices) {
derivatives[i] *= frictions[i]
}
for (i in 1..derivatives.size - 1) {
for (i in 1 until derivatives.size) {
derivatives[i] += derivatives[i - 1]
}
val dy = derivatives[derivatives.size - 1]
@@ -243,12 +243,12 @@ fun Node.installTooltip(openDelay: Double = 1000.0, visibleDelay: Double = 5000.
}
fun JFXTextField.setValidateWhileTextChanged() {
textProperty().addListener { _ -> validate() }
textProperty().onInvalidated(this::validate)
validate()
}
fun JFXPasswordField.setValidateWhileTextChanged() {
textProperty().addListener { _ -> validate() }
textProperty().onInvalidated(this::validate)
validate()
}

View File

@@ -89,7 +89,7 @@ class LeftPaneController(private val leftPane: AdvancedListBox) {
profilePane.children
.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() {

View File

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

View File

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

View File

@@ -35,6 +35,7 @@ import javafx.scene.paint.Paint
import javafx.scene.shape.Rectangle
import org.jackhuang.hmcl.util.getValue
import org.jackhuang.hmcl.util.onChange
import org.jackhuang.hmcl.util.onInvalidated
import org.jackhuang.hmcl.util.setValue
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
this.buttonContainer.isPickOnBounds = false
this.buttonContainer.shapeProperty().bind(shapeProperty())
@@ -136,8 +137,8 @@ open class RipplerContainer(@NamedArg("container") container: Node): StackPane()
this.updateChildren()
containerProperty.addListener { _ -> updateChildren() }
selectedProperty.addListener { _ ->
containerProperty.onInvalidated(this::updateChildren)
selectedProperty.onInvalidated {
if (selected) background = Background(BackgroundFill(ripplerFill, 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.wizard.WizardController
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 {
@@ -50,9 +51,7 @@ class InstallersPage(private val controller: WizardController, private val repos
val gameVersion = controller.settings["game"] as String
txtName.validators += Validator { !repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") }
txtName.textProperty().addListener { _ ->
btnInstall.isDisable = !txtName.validate()
}
txtName.textProperty().onInvalidated { btnInstall.isDisable = !txtName.validate() }
txtName.text = gameVersion
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.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage
import org.jackhuang.hmcl.util.onInvalidated
class ModpackPage(private val controller: WizardController): StackPane(), WizardPage {
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
lblModpackLocation.text = selectedFile.absolutePath
txtModpackName.validators += Validator { !profile.repository.hasVersion(it) && it.isNotBlank() }.apply { message = i18n("version.already_exists") }
txtModpackName.textProperty().addListener { _ ->
btnInstall.isDisable = !txtModpackName.validate()
}
txtModpackName.textProperty().onInvalidated { btnInstall.isDisable = !txtModpackName.validate() }
try {
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.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage
import org.jackhuang.hmcl.util.onInvalidated
class ModpackInfoPage(private val controller: WizardController, version: String): StackPane(), WizardPage {
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")
scroll.smoothScrolling()
txtModpackName.text = version
txtModpackName.textProperty().addListener { _ -> checkValidation() }
txtModpackAuthor.textProperty().addListener { _ -> checkValidation() }
txtModpackVersion.textProperty().addListener { _ -> checkValidation() }
txtModpackName.textProperty().onInvalidated(this::checkValidation)
txtModpackAuthor.textProperty().onInvalidated(this::checkValidation)
txtModpackVersion.textProperty().onInvalidated(this::checkValidation)
txtModpackAuthor.text = Settings.selectedAccount?.username ?: ""
lblVersionName.text = version
}
fun checkValidation() {
private fun checkValidation() {
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) =
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()
}

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 {
addListener(ListChangeListener { op(it) })
}
fun <T> ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }

View File

@@ -27,6 +27,7 @@ buildscript {
}
dependencies {
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 "com.google.code.gson:gson:2.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'
}