1.6 minimize

This commit is contained in:
sky 2021-06-30 17:47:43 +08:00
parent becb3f3578
commit bba80af506
5 changed files with 307 additions and 7 deletions

View File

@ -23,6 +23,7 @@ dependencies {
compile localGroovy()
embed 'org.ow2.asm:asm:8.0.1'
embed 'org.ow2.asm:asm-commons:8.0.1'
embed 'com.google.code.gson:gson:2.8.7'
}
jar {

View File

@ -0,0 +1,205 @@
package io.izzel.taboolib.gradle
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.gradle.api.Project
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import java.nio.charset.StandardCharsets
class Description {
def authors
def contributors
def depend
def softdepend
def loadbefore
def website
def prefix
def load
def api = "1.0.0"
def apiVersion = '1.13'
def libraries
def dependencies = "spongeapi@7.2.0"
def requiredMods = "spongeapi@7.2.0"
static List<String> buildFile() {
def str = []
str += ""
str += ""
str += "# Powered by TabooLib 6.0 #"
str += ""
str += ""
return str
}
static def appendName(str, any, key) {
if (any != null) {
str.add("$key: $any")
}
}
static def appendNameList(str, any, key) {
if (any instanceof List<String>) {
str.add("$key:")
for (i in any) {
str.add(" - '${i}'")
}
} else if (any != null) {
str.add("$key:")
str.add(" - '${any}'")
}
}
byte[] buildBukkitFile(Project project) {
def str = buildFile()
str += "name: ${project.name}"
str += "main: ${project.group}.taboolib.platform.BukkitPlugin"
appendName(str, load, "load")
str += "version: ${project.version}"
if (apiVersion != null) {
str += "api-version: ${apiVersion}"
}
appendName(str, prefix, "prefix")
appendName(str, website, "website")
appendNameList(str, authors, "authors")
appendNameList(str, contributors, "contributors")
appendNameList(str, depend, "depend")
appendNameList(str, softdepend, "softdepend")
appendNameList(str, loadbefore, "loadbefore")
appendNameList(str, libraries, "libraries")
return str.join("\n").getBytes(StandardCharsets.UTF_8)
}
byte[] buildBungeeFile(Project project) {
def str = buildFile()
str += "name: ${project.name}"
str += "main: ${project.group}.taboolib.platform.BungeePlugin"
str += "version: ${project.version}"
appendName(str, authors, "author")
appendNameList(str, depend, "depends")
appendNameList(str, softdepend, "softDepends")
appendNameList(str, libraries, "libraries")
return str.join("\n").getBytes(StandardCharsets.UTF_8)
}
byte[] buildNukkitFile(Project project) {
def str = buildFile()
str += "name: ${project.name}"
str += "main: ${project.group}.taboolib.platform.NukkitPlugin"
appendName(str, load, "load")
str += "version: ${project.version}"
if (api != null) {
str += "api: ${api}"
}
appendName(str, prefix, "prefix")
appendName(str, website, "website")
appendNameList(str, authors, "authors")
appendNameList(str, depend, "depend")
appendNameList(str, softdepend, "softdepend")
appendNameList(str, loadbefore, "loadbefore")
appendNameList(str, libraries, "libraries")
return str.join("\n").getBytes(StandardCharsets.UTF_8)
}
byte[] buildSpongeFile(Project project) {
def base = new JsonArray()
def info = new JsonObject()
info.addProperty("modid", project.name.toLowerCase())
info.addProperty("name", project.name)
info.addProperty("version", project.version.toString())
if (website != null) {
info.addProperty("url", website.toString())
}
if (authors instanceof List<String>) {
def arr = new JsonArray()
authors.each { arr.add(it) }
info.add("authorList", arr)
} else if (authors != null) {
def arr = new JsonArray()
arr.add(authors.toString())
info.add("authorList", arr)
}
if (dependencies instanceof List<String>) {
def arr = new JsonArray()
dependencies.each { arr.add(it) }
info.add("dependencies", arr)
} else if (dependencies != null) {
def arr = new JsonArray()
arr.add(dependencies.toString())
info.add("dependencies", arr)
}
if (requiredMods instanceof List<String>) {
def arr = new JsonArray()
requiredMods.each { arr.add(it) }
info.add("requiredMods", arr)
} else if (requiredMods != null) {
def arr = new JsonArray()
arr.add(requiredMods.toString())
info.add("requiredMods", arr)
}
base.add(info)
return new GsonBuilder().setPrettyPrinting().create().toJson(base).getBytes(StandardCharsets.UTF_8)
}
def author(author) {
this.authors = author
}
def contributor(contributor) {
this.contributors = contributor
}
def authors(author) {
this.authors = author
}
def contributors(contributor) {
this.contributors = contributor
}
def depend(depend) {
this.depend = depend
}
def softdepend(softdepend) {
this.softdepend = softdepend
}
def loadbefore(loadbefore) {
this.loadbefore = loadbefore
}
def website(website) {
this.website = website
}
def prefix(prefix) {
this.prefix = prefix
}
def load(load) {
this.load = load
}
def api(api) {
this.api = api
}
def apiVersion(apiVersion) {
this.apiVersion = apiVersion
}
def libraries(libraries) {
this.libraries = libraries
}
def dependencies(dependencies) {
this.dependencies = dependencies
}
def requiredMods(requiredMods) {
this.requiredMods = requiredMods
}
}

View File

@ -16,6 +16,7 @@ import java.nio.file.StandardCopyOption
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
import java.util.stream.Collectors
@ToString
class RelocateJar extends DefaultTask {
@ -33,24 +34,25 @@ class RelocateJar extends DefaultTask {
@Input
Project project
@Input
TabooLibExtension tabooExt
@TaskAction
def relocate() {
def isolated = new TreeMap<String, List<String>>()
def mapping = relocations.collectEntries { [(it.key.replace('.', '/')), it.value.replace('.', '/')] }
def remapper = new RelocateRemapper(relocations, mapping as Map<String, String>)
def index = inJar.name.lastIndexOf('.')
def name = inJar.name.substring(0, index) + (classifier == null ? "" : "-" + classifier) + inJar.name.substring(index)
def outJar = new File(inJar.getParentFile(), name)
def tmpOut = File.createTempFile(name, ".jar")
def isolated = new HashMap<String, List<String>>()
new JarOutputStream(new FileOutputStream(tmpOut)).withCloseable { out ->
project.logger.info(outJar.getAbsolutePath())
def tempOut1 = File.createTempFile(name, ".jar")
new JarOutputStream(new FileOutputStream(tempOut1)).withCloseable { out ->
int n
def buf = new byte[32768]
new JarFile(inJar).withCloseable { jarFile ->
for (def jarEntry : jarFile.entries()) {
jarFile.entries().each { def jarEntry ->
jarFile.getInputStream(jarEntry).withCloseable {
if (jarEntry.name.endsWith(".class")) {
project.logger.info("Relocating " + jarEntry.name)
def reader = new ClassReader(it)
def writer = new ClassWriter(0)
def visitor = new TabooLibClassVisitor(writer, project)
@ -70,6 +72,90 @@ class RelocateJar extends DefaultTask {
}
}
}
Files.copy(tmpOut.toPath(), outJar.toPath(), StandardCopyOption.REPLACE_EXISTING)
def use = new TreeMap<String, Set<String>>()
remapper.use.each {
it.value.each { e ->
def key = relocate(project, getNameWithOutExtension(e))
def value = relocate(project, getNameWithOutExtension(it.key))
use.computeIfAbsent(key) { new HashSet() }.add(value)
}
}
def transfer = new TreeMap()
isolated.each {
transfer[relocate(project, it.key)] = it.value.stream().map { i -> relocate(project, i) }.collect(Collectors.toList())
}
isolated = transfer
def tempOut2 = File.createTempFile(name, ".jar")
new JarOutputStream(new FileOutputStream(tempOut2)).withCloseable { out ->
int n
def buf = new byte[32768]
def del = new HashSet()
def exclude = new HashSet()
new JarFile(tempOut1).withCloseable { jarFile ->
jarFile.entries().each { def jarEntry ->
jarFile.getInputStream(jarEntry).withCloseable {
if (jarEntry.name.endsWith(".class")) {
def nameWithOutExtension = getNameWithOutExtension(jarEntry.name)
if (use.containsKey(nameWithOutExtension.toString()) && !exclude.contains(nameWithOutExtension)) {
exclude.add(nameWithOutExtension)
if (isIsolated(use, use[nameWithOutExtension], isolated, nameWithOutExtension)) {
println(" Isolated ${nameWithOutExtension}")
del.add(nameWithOutExtension)
}
}
}
if (!del.contains(getNameWithOutExtension(jarEntry.name))) {
out.putNextEntry(new JarEntry(jarEntry.name))
while ((n = it.read(buf)) != -1) {
out.write(buf, 0, n)
}
}
}
}
if (tabooExt.modules.contains("platform-bukkit")) {
out.putNextEntry(new JarEntry("plugin.yml"))
out.write(tabooExt.description.buildBukkitFile(project))
}
if (tabooExt.modules.contains("platform-nukkit")) {
out.putNextEntry(new JarEntry("nukkit.yml"))
out.write(tabooExt.description.buildNukkitFile(project))
}
if (tabooExt.modules.contains("platform-bungee")) {
out.putNextEntry(new JarEntry("bungee.yml"))
out.write(tabooExt.description.buildBungeeFile(project))
}
if (tabooExt.modules.contains("platform-sponge")) {
out.putNextEntry(new JarEntry("mcmod.info"))
out.write(tabooExt.description.buildSpongeFile(project))
}
}
}
Files.copy(tempOut2.toPath(), outJar.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
static String getNameWithOutExtension(name) {
if (name.contains('$')) {
return name.substring(0, name.indexOf('$')).replace('.', '/')
} else if (name.contains('.')) {
return name.substring(0, name.lastIndexOf('.')).replace('.', '/')
} else {
return name.replace('.', '/')
}
}
static String relocate(Project project, String name) {
if (name.startsWith("taboolib")) {
return project.group.toString().replace('.', '/') + '/' + name.replace('.', '/')
} else {
return name.replace('.', '/')
}
}
static boolean isIsolated(Map<String, Set<String>> use, Set<String> refer, Map<String, List<String>> isolated, String nameWithOutExtension) {
if (isolated.containsKey(nameWithOutExtension)) {
return refer.size() <= 1 || refer.stream().allMatch { nameWithOutExtension == it || isolated[nameWithOutExtension].contains(it) || isIsolated(use, use[it], isolated, it) }
} else {
return false
}
}
}

View File

@ -1,6 +1,7 @@
package io.izzel.taboolib.gradle
import groovy.transform.Canonical
import org.codehaus.groovy.runtime.DefaultGroovyMethods
@Canonical
class TabooLibExtension {
@ -11,6 +12,8 @@ class TabooLibExtension {
List<String> modules = []
Description description = new Description()
Map<String, String> relocation = new LinkedHashMap<>()
def install(String... name) {
@ -20,4 +23,8 @@ class TabooLibExtension {
def relocate(String pre, String post) {
relocation[pre] = post
}
def descriptionFile(@DelegatesTo(Description.class) Closure<Description> closure) {
DefaultGroovyMethods.with(description, closure)
}
}

View File

@ -25,6 +25,7 @@ class TabooLibPlugin implements Plugin<Project> {
}
def jarTask = project.tasks.jar as Jar
tabooTask.configure { RelocateJar task ->
task.tabooExt = tabooExt
task.project = project
task.inJar = task.inJar ?: jarTask.archivePath
task.relocations = tabooExt.relocation