2020-05-03 19:21:54 +08:00
|
|
|
buildscript {
|
2021-04-29 15:00:34 +08:00
|
|
|
repositories {
|
|
|
|
gradlePluginPortal()
|
2021-07-10 22:44:13 +08:00
|
|
|
maven { url 'https://jitpack.io' }
|
2021-04-29 15:00:34 +08:00
|
|
|
}
|
2020-05-03 19:21:54 +08:00
|
|
|
dependencies {
|
|
|
|
classpath 'org.tukaani:xz:1.8'
|
2021-07-10 22:44:13 +08:00
|
|
|
classpath 'org.glavo:pack200:0.3.0'
|
2021-09-30 19:38:51 +08:00
|
|
|
|
|
|
|
classpath 'com.guardsquare:proguard-gradle:7.1.0' // The ProGuard Gradle plugin.
|
2020-05-03 19:21:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-05 11:06:50 +08:00
|
|
|
plugins {
|
2018-10-03 19:20:47 +08:00
|
|
|
id 'application'
|
2021-04-29 15:00:34 +08:00
|
|
|
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
2018-08-05 11:06:50 +08:00
|
|
|
}
|
|
|
|
|
2018-07-31 19:39:21 +08:00
|
|
|
import java.nio.file.FileSystems
|
|
|
|
import java.security.KeyFactory
|
2017-08-10 19:34:19 +08:00
|
|
|
import java.security.MessageDigest
|
2018-07-31 19:39:21 +08:00
|
|
|
import java.security.Signature
|
|
|
|
import java.security.spec.PKCS8EncodedKeySpec
|
2018-08-04 22:12:02 +08:00
|
|
|
import java.util.jar.JarFile
|
|
|
|
import java.util.jar.JarOutputStream
|
2018-08-05 09:37:55 +08:00
|
|
|
import java.util.zip.GZIPOutputStream
|
2018-07-31 19:39:21 +08:00
|
|
|
import java.util.zip.ZipFile
|
2018-08-04 22:12:02 +08:00
|
|
|
import java.nio.file.Files
|
2017-08-10 19:34:19 +08:00
|
|
|
|
2018-08-05 01:02:42 +08:00
|
|
|
import org.tukaani.xz.LZMA2Options
|
|
|
|
import org.tukaani.xz.XZOutputStream
|
2021-07-10 22:44:13 +08:00
|
|
|
import org.glavo.pack200.Pack200
|
2018-08-05 01:02:42 +08:00
|
|
|
|
2021-05-25 18:45:42 +08:00
|
|
|
def dev = null
|
|
|
|
def shortcommit = System.getenv("GITHUB_SHA")?.toLowerCase()?.substring(0, 7) ?: null
|
|
|
|
if (shortcommit != null && !shortcommit.isEmpty()) dev = "dev-" + shortcommit
|
2021-05-25 18:08:13 +08:00
|
|
|
def buildnumber = System.getenv("BUILD_NUMBER") ?: dev ?: "SNAPSHOT"
|
2018-09-08 19:41:02 +08:00
|
|
|
if (System.getenv("BUILD_NUMBER") != null && System.getenv("BUILD_NUMBER_OFFSET") != null)
|
|
|
|
buildnumber = (Integer.parseInt(System.getenv("BUILD_NUMBER")) - Integer.parseInt(System.getenv("BUILD_NUMBER_OFFSET"))).toString()
|
2021-08-28 19:48:57 +08:00
|
|
|
def versionroot = System.getenv("VERSION_ROOT") ?: "3.4"
|
2021-08-23 11:44:10 +08:00
|
|
|
def microsoftAuthId = System.getenv("MICROSOFT_AUTH_ID") ?: ""
|
2021-08-22 20:35:30 +08:00
|
|
|
def microsoftAuthSecret = System.getenv("MICROSOFT_AUTH_SECRET") ?: ""
|
2021-09-28 17:09:19 +08:00
|
|
|
def versionType = System.getenv("VERSION_TYPE") ?: "nightly"
|
2018-07-31 13:46:31 +08:00
|
|
|
version = versionroot + '.' + buildnumber
|
2017-08-10 19:34:19 +08:00
|
|
|
|
2018-10-02 12:15:52 +08:00
|
|
|
mainClassName = 'org.jackhuang.hmcl.Main'
|
|
|
|
|
2015-06-22 16:47:05 +08:00
|
|
|
dependencies {
|
2021-04-29 15:00:34 +08:00
|
|
|
implementation project(":HMCLCore")
|
2021-09-06 00:45:25 +08:00
|
|
|
implementation project(":JSTUN")
|
2021-04-29 15:00:34 +08:00
|
|
|
implementation rootProject.files("lib/JFoenix.jar")
|
2017-08-10 19:34:19 +08:00
|
|
|
}
|
|
|
|
|
2018-07-31 19:39:21 +08:00
|
|
|
def digest(String algorithm, byte[] bytes) {
|
|
|
|
return MessageDigest.getInstance(algorithm).digest(bytes)
|
|
|
|
}
|
|
|
|
|
2018-07-31 15:48:29 +08:00
|
|
|
def createChecksum(File file) {
|
|
|
|
def algorithm = "SHA-1"
|
|
|
|
def suffix = "sha1"
|
2018-07-31 19:39:21 +08:00
|
|
|
new File(file.parentFile, file.name + "." + suffix).text = digest(algorithm, file.bytes).encodeHex().toString() + "\n"
|
|
|
|
}
|
|
|
|
|
2018-08-04 22:12:02 +08:00
|
|
|
def attachSignature(File jar) {
|
2018-07-31 19:39:21 +08:00
|
|
|
def keyLocation = System.getenv("HMCL_SIGNATURE_KEY");
|
2018-08-04 22:12:02 +08:00
|
|
|
if (keyLocation == null)
|
|
|
|
return
|
2018-07-31 19:39:21 +08:00
|
|
|
def privatekey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(new File(keyLocation).bytes))
|
|
|
|
|
|
|
|
def signer = Signature.getInstance("SHA512withRSA")
|
|
|
|
signer.initSign(privatekey)
|
2018-08-04 22:12:02 +08:00
|
|
|
new ZipFile(jar).withCloseable { zip ->
|
2018-07-31 19:39:21 +08:00
|
|
|
zip.stream()
|
2018-08-04 22:12:02 +08:00
|
|
|
.sorted(Comparator.comparing { it.name })
|
|
|
|
.filter { it.name != "META-INF/hmcl_signature" }
|
|
|
|
.forEach {
|
2018-08-05 00:42:05 +08:00
|
|
|
signer.update(digest("SHA-512", it.name.getBytes("UTF-8")))
|
|
|
|
signer.update(digest("SHA-512", zip.getInputStream(it).bytes))
|
|
|
|
}
|
2018-07-31 19:39:21 +08:00
|
|
|
}
|
|
|
|
def signature = signer.sign()
|
|
|
|
|
2018-08-04 22:12:02 +08:00
|
|
|
FileSystems.newFileSystem(URI.create("jar:" + jar.toURI()), [:]).withCloseable { zipfs ->
|
2018-08-05 09:37:55 +08:00
|
|
|
Files.newOutputStream(zipfs.getPath("META-INF/hmcl_signature")).withCloseable { it << signature }
|
2018-07-31 19:39:21 +08:00
|
|
|
}
|
2018-07-31 15:48:29 +08:00
|
|
|
}
|
|
|
|
|
2018-08-05 00:42:05 +08:00
|
|
|
ext.packer = Pack200.newPacker()
|
|
|
|
packer.properties()["pack.effort"] = "9"
|
|
|
|
ext.unpacker = Pack200.newUnpacker()
|
|
|
|
|
2021-04-26 11:49:05 +08:00
|
|
|
// Pack200 does not guarantee that unpacked .class file is bit-wise same as the .class file before packing
|
|
|
|
// because of shrinking. So we should pack .class files and unpack it to make sure that after unpacking
|
|
|
|
// .class files remain the same.
|
2018-08-05 00:42:05 +08:00
|
|
|
def repack(File file) {
|
|
|
|
def packed = new ByteArrayOutputStream()
|
|
|
|
new JarFile(file).withCloseable { packer.pack(it, packed) }
|
|
|
|
new JarOutputStream(file.newOutputStream()).withCloseable { unpacker.unpack(new ByteArrayInputStream(packed.toByteArray()), it) }
|
|
|
|
}
|
|
|
|
|
2021-04-15 06:22:56 +08:00
|
|
|
sourceSets {
|
|
|
|
java11 {
|
|
|
|
java {
|
|
|
|
srcDirs = ['src/main/java11']
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-16 04:00:17 +08:00
|
|
|
compileJava11Java {
|
2021-07-10 22:44:13 +08:00
|
|
|
if(JavaVersion.current() < JavaVersion.VERSION_11) {
|
|
|
|
javaCompiler = javaToolchains.compilerFor {
|
|
|
|
languageVersion = JavaLanguageVersion.of(11)
|
|
|
|
}
|
2021-04-15 06:22:56 +08:00
|
|
|
}
|
2021-04-16 04:00:17 +08:00
|
|
|
options.compilerArgs.add('--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED')
|
|
|
|
sourceCompatibility = 11
|
|
|
|
targetCompatibility = 11
|
|
|
|
}
|
|
|
|
|
|
|
|
jar {
|
2021-04-29 15:00:34 +08:00
|
|
|
enabled = false
|
|
|
|
dependsOn shadowJar
|
|
|
|
}
|
|
|
|
|
|
|
|
shadowJar {
|
|
|
|
classifier = null
|
|
|
|
|
2017-08-10 19:34:19 +08:00
|
|
|
manifest {
|
2021-08-22 20:35:30 +08:00
|
|
|
attributes 'Created-By': 'Copyright(c) 2013-2021 huangyuhui.',
|
2018-10-02 12:15:52 +08:00
|
|
|
'Main-Class': mainClassName,
|
2018-08-04 22:12:02 +08:00
|
|
|
'Multi-Release': 'true',
|
2021-08-20 15:58:44 +08:00
|
|
|
'Implementation-Version': project.version,
|
2021-08-23 11:44:10 +08:00
|
|
|
'Microsoft-Auth-Id': microsoftAuthId,
|
2021-08-22 20:35:30 +08:00
|
|
|
'Microsoft-Auth-Secret': microsoftAuthSecret,
|
2021-09-28 17:09:19 +08:00
|
|
|
'Build-Channel': versionType,
|
2021-07-10 22:44:13 +08:00
|
|
|
'Class-Path': 'pack200.jar',
|
2020-07-20 16:17:31 +08:00
|
|
|
'Add-Opens': [
|
2021-04-16 04:00:17 +08:00
|
|
|
'java.base/java.lang',
|
2020-07-20 16:17:31 +08:00
|
|
|
'java.base/java.lang.reflect',
|
|
|
|
'javafx.graphics/javafx.css',
|
|
|
|
'javafx.base/com.sun.javafx.runtime',
|
|
|
|
'javafx.controls/com.sun.javafx.scene.control.behavior',
|
|
|
|
'javafx.controls/javafx.scene.control.skin',
|
|
|
|
'javafx.controls/com.sun.javafx.scene.control',
|
|
|
|
'javafx.base/com.sun.javafx.binding',
|
|
|
|
'javafx.base/com.sun.javafx.event',
|
|
|
|
'javafx.graphics/com.sun.javafx.stage'
|
|
|
|
].join(" "),
|
|
|
|
'Add-Exports': [
|
2021-04-15 06:22:56 +08:00
|
|
|
'java.base/jdk.internal.loader',
|
2020-07-20 16:17:31 +08:00
|
|
|
'javafx.controls/com.sun.javafx.scene.control.behavior',
|
|
|
|
'javafx.controls/javafx.scene.control.skin',
|
|
|
|
'javafx.controls/com.sun.javafx.scene.control',
|
|
|
|
'javafx.base/com.sun.javafx.binding',
|
|
|
|
'javafx.graphics/com.sun.javafx.stage',
|
|
|
|
'javafx.base/com.sun.javafx.event'
|
|
|
|
].join(" ")
|
2017-08-10 19:34:19 +08:00
|
|
|
}
|
2018-08-05 11:06:50 +08:00
|
|
|
|
2017-08-10 19:34:19 +08:00
|
|
|
doLast {
|
2021-04-26 11:49:05 +08:00
|
|
|
repack(jar.archivePath) // see repack()
|
2018-08-05 11:06:50 +08:00
|
|
|
attachSignature(jar.archivePath)
|
|
|
|
createChecksum(jar.archivePath)
|
2017-08-10 19:34:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 19:38:51 +08:00
|
|
|
task proguard(type: proguard.gradle.ProGuardTask) {
|
|
|
|
dependsOn shadowJar
|
|
|
|
injars shadowJar
|
|
|
|
|
|
|
|
outjars "${buildDir}/libs/${project.name}-${project.version}-proguard.jar"
|
|
|
|
|
|
|
|
|
|
|
|
dontobfuscate
|
|
|
|
dontoptimize
|
2021-10-17 16:29:14 +08:00
|
|
|
dontpreverify
|
|
|
|
printusage
|
|
|
|
|
|
|
|
keep 'public class org.jackhuang.** { *; }'
|
|
|
|
keepclassmembers 'public class org.jackhuang.** { *; }'
|
|
|
|
keep 'public class com.jfoenix.** { *; }'
|
|
|
|
keepclassmembers 'public class com.jfoenix.** { *; }'
|
2021-09-30 19:38:51 +08:00
|
|
|
|
|
|
|
dontwarn 'com.nqzero.**'
|
|
|
|
dontwarn 'org.slf4j.**'
|
|
|
|
dontwarn 'org.jackhuang.hmcl.util.Pack200Utils'
|
2021-10-17 03:24:05 +08:00
|
|
|
dontwarn 'com.sun.javafx.**'
|
|
|
|
dontwarn 'com.jfoenix.**'
|
2021-09-30 19:38:51 +08:00
|
|
|
|
|
|
|
adaptclassstrings
|
|
|
|
|
|
|
|
// next block taken verbatim from Proguard's documentation examples:
|
|
|
|
|
|
|
|
libraryjars files(configurations.compileClasspath.collect())
|
|
|
|
|
|
|
|
keepattributes 'SourceFile,LineNumberTable'
|
|
|
|
|
2021-10-17 03:24:05 +08:00
|
|
|
var javaHome = System.getProperty('java.home')
|
|
|
|
|
2021-09-30 19:38:51 +08:00
|
|
|
// Automatically handle the Java version of this build.
|
2021-10-17 03:24:05 +08:00
|
|
|
if (System.getProperty('java.version').startsWith('1.')) {
|
|
|
|
// Before Java 9, the runtime classes were packaged in a single jar file.
|
|
|
|
libraryjars "${javaHome}/lib/rt.jar"
|
|
|
|
libraryjars "${javaHome}/lib/ext/jfxrt.jar"
|
|
|
|
} else {
|
|
|
|
// As of Java 9, the runtime classes are packaged in modular jmod files.
|
|
|
|
libraryjars "${javaHome}/jmods/java.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/java.desktop.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/java.logging.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/java.management.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/java.sql.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/java.xml.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
|
|
|
|
libraryjars "${javaHome}/jmods/jdk.management.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/jdk.unsupported.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
|
|
|
|
if (new File("${javaHome}/jmods/javafx.base.jmod").exists()) {
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.controls.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.graphics.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.media.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.fxml.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
libraryjars "${javaHome}/jmods/javafx.web.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 19:38:51 +08:00
|
|
|
}
|
|
|
|
|
2021-10-18 01:00:05 +08:00
|
|
|
task finalJar(type: Jar) {
|
|
|
|
dependsOn proguard
|
|
|
|
|
|
|
|
classifier = 'final'
|
|
|
|
|
|
|
|
from { proguard.outJarFiles.collect { zipTree(it)} }
|
|
|
|
|
|
|
|
into('/') {
|
|
|
|
from { shadowJar.outputs.files.collect { zipTree(it) } }
|
|
|
|
include("META-INF/versions/**")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 15:48:29 +08:00
|
|
|
def createExecutable(String suffix, String header) {
|
|
|
|
def output = new File(jar.archivePath.parentFile, jar.archivePath.name[0..-4] + suffix)
|
|
|
|
output.bytes = new File(project.projectDir, header).bytes
|
|
|
|
output << jar.archivePath.bytes
|
|
|
|
createChecksum(output)
|
|
|
|
}
|
2018-07-19 00:54:48 +08:00
|
|
|
|
2018-11-11 21:12:03 +08:00
|
|
|
processResources {
|
2018-11-25 23:42:48 +08:00
|
|
|
ext.convertToBSS = { String resource ->
|
2019-03-04 11:39:30 +08:00
|
|
|
// exclude resource
|
2018-11-23 17:08:17 +08:00
|
|
|
doFirst {
|
|
|
|
def cssFile = new File(this.projectDir, "src/main/resources/" + resource)
|
|
|
|
def bssFile = new File(this.projectDir, "build/compiled-resources/" + resource[0..-4] + "bss")
|
|
|
|
bssFile.parentFile.mkdirs()
|
2021-07-10 22:44:13 +08:00
|
|
|
javaexec {
|
2021-09-20 13:27:09 +08:00
|
|
|
classpath = sourceSets.main.compileClasspath
|
2021-09-17 20:00:10 +08:00
|
|
|
mainClass = "com.sun.javafx.css.parser.Css2Bin"
|
2021-07-10 22:44:13 +08:00
|
|
|
args = [cssFile, bssFile]
|
2018-11-25 23:42:48 +08:00
|
|
|
}
|
2018-11-11 21:12:03 +08:00
|
|
|
}
|
|
|
|
}
|
2018-11-23 17:08:17 +08:00
|
|
|
from "build/compiled-resources"
|
|
|
|
|
|
|
|
convertToBSS "assets/css/root.css"
|
|
|
|
convertToBSS "assets/css/blue.css"
|
2021-04-29 15:00:34 +08:00
|
|
|
|
|
|
|
into('META-INF/versions/11') {
|
|
|
|
from sourceSets.java11.output
|
|
|
|
}
|
|
|
|
dependsOn java11Classes
|
2018-11-11 21:12:03 +08:00
|
|
|
}
|
|
|
|
|
2018-08-05 09:37:55 +08:00
|
|
|
task makePack(dependsOn: jar) {
|
|
|
|
ext.outputPath = new File(jar.archivePath.parentFile, jar.archivePath.name[0..-4] + "pack")
|
|
|
|
doLast {
|
|
|
|
outputPath.newOutputStream().withCloseable { out ->
|
|
|
|
new JarFile(jar.archivePath).withCloseable { jarFile -> packer.pack(jarFile, out) }
|
|
|
|
}
|
|
|
|
createChecksum(outputPath)
|
2018-08-04 22:12:02 +08:00
|
|
|
}
|
2018-08-05 09:37:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
task makePackXz(dependsOn: makePack) doLast {
|
|
|
|
def packXz = new File(makePack.outputPath.parentFile, makePack.outputPath.name + ".xz")
|
2021-04-26 11:49:05 +08:00
|
|
|
// Our CI server does not have enough memory space to compress file at highest level.
|
2019-03-19 11:11:59 +08:00
|
|
|
new XZOutputStream(packXz.newOutputStream(), new LZMA2Options(5)).withCloseable { it << makePack.outputPath.bytes }
|
2018-08-05 09:37:55 +08:00
|
|
|
createChecksum(packXz)
|
|
|
|
}
|
2018-08-04 22:12:02 +08:00
|
|
|
|
2018-08-05 09:37:55 +08:00
|
|
|
task makePackGz(dependsOn: makePack) doLast {
|
|
|
|
def packGz = new File(makePack.outputPath.parentFile, makePack.outputPath.name + ".gz")
|
|
|
|
new GZIPOutputStream(packGz.newOutputStream()).withCloseable { it << makePack.outputPath.bytes }
|
|
|
|
createChecksum(packGz)
|
2018-08-04 22:12:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-31 15:48:29 +08:00
|
|
|
task makeExecutables(dependsOn: jar) doLast {
|
|
|
|
createExecutable("exe", "src/main/resources/assets/HMCLauncher.exe")
|
2017-08-27 12:49:56 +08:00
|
|
|
}
|
|
|
|
|
2018-08-05 01:02:42 +08:00
|
|
|
build.dependsOn makePackXz
|
2018-08-05 09:37:55 +08:00
|
|
|
build.dependsOn makePackGz
|
2021-05-25 18:08:13 +08:00
|
|
|
build.dependsOn makeExecutables
|