Compare commits

..

34 Commits
1.4 ... master

Author SHA1 Message Date
坏黑 be620a1247 1.27 Fix website 2021-09-13 23:14:19 +08:00
坏黑 b7d5a97452 1.26 2021-08-25 16:19:52 +08:00
坏黑 ce8fe9c4bf 1.26 2021-08-25 16:19:20 +08:00
坏黑 8596bcae2c 1.25 2021-08-23 16:42:16 +08:00
坏黑 9dfb9d1876 1.24 2021-08-23 14:26:01 +08:00
坏黑 9c88efae69 Merge branch 'master' of https://github.com/TabooLib/taboolib-gradle-plugin
# Conflicts:
#	build.gradle
2021-08-23 14:11:32 +08:00
坏黑 43fc609549 1.23 2021-08-23 14:10:09 +08:00
坏黑 07512c45d9
Update build.gradle 2021-08-19 17:43:03 +08:00
坏黑 2a93a9e3d5
Merge pull request #7 from Itsusinn/master
build: update asm version
2021-08-19 17:42:48 +08:00
坏黑 3360b596d5
Update build.gradle 2021-08-19 17:40:53 +08:00
坏黑 8633b8e40d 1.20 2021-08-19 17:14:08 +08:00
坏黑 49751521f8 1.19 2021-08-19 16:06:03 +08:00
itsusinn 329f659f41
build: update asm version
support java bytecode version 16,17,18
2021-08-19 09:12:24 +08:00
坏黑 b53a0d68d2 1.18 2021-08-16 22:37:07 +08:00
坏黑 ec7038c311 1.17 2021-08-15 21:17:37 +08:00
坏黑 4d2bbc8054 1.16 2021-08-15 03:57:11 +08:00
坏黑 578b820dfe 1.14 2021-08-02 15:49:38 +08:00
坏黑 943f2679f9 1.13 2021-08-02 15:15:27 +08:00
坏黑 aefa846d3c
Merge pull request #5 from Itsusinn/master
fix(RelocateJar): ZipException due to duplicate files
2021-07-29 20:51:37 +08:00
坏黑 2340a7d726 1.12 2021-07-29 20:13:29 +08:00
坏黑 651feab7e7 1.11 2021-07-29 20:04:15 +08:00
itsusinn 47fa2ddc0a
fix(RelocateJar): ZipException due to duplicate files 2021-07-29 17:59:31 +08:00
sky a3445b4482 1.10 2021-07-27 16:48:31 +08:00
sky aeff5b4ad4 1.9 2021-07-19 14:56:00 +08:00
sky 3dcbff0684 1.8 2021-07-11 00:54:47 +08:00
sky 438eff19da + update description file generator 2021-07-11 00:54:35 +08:00
sky 170c7e26bf + update custom description node 2021-07-08 01:09:24 +08:00
sky 56b8eaa9a7 sponge api8 2021-07-08 01:00:54 +08:00
sky 66f4ba911f 1.7 velocity support 2021-07-03 00:37:34 +08:00
sky bba80af506 1.6 minimize 2021-06-30 17:47:43 +08:00
sky becb3f3578 1.5 test minimize 2021-06-30 01:52:52 +08:00
sky 4e8d42f4b9 1.5 test minimize 2021-06-29 23:29:22 +08:00
sky 84ef9b98db 1.5 2021-06-27 21:17:57 +08:00
坏黑 81f9cfdc42
Merge pull request #3 from TabooLib/1.4
1.4 test
2021-06-27 15:47:48 +08:00
29 changed files with 1321 additions and 30 deletions

View File

@ -3,10 +3,13 @@ plugins {
id 'maven-publish' id 'maven-publish'
id 'java-gradle-plugin' id 'java-gradle-plugin'
id 'com.gradle.plugin-publish' version '0.12.0' id 'com.gradle.plugin-publish' version '0.12.0'
id 'org.jetbrains.kotlin.jvm' version '1.5.10'
} }
apply plugin: 'kotlin'
group 'io.izzel.taboolib' group 'io.izzel.taboolib'
version '1.4' version '1.27'
configurations { configurations {
embed embed
@ -21,8 +24,10 @@ dependencies {
compile 'org.codehaus.groovy:groovy:2.5.13' compile 'org.codehaus.groovy:groovy:2.5.13'
compile gradleApi() compile gradleApi()
compile localGroovy() compile localGroovy()
embed 'org.ow2.asm:asm:8.0.1' embed 'org.ow2.asm:asm:9.2'
embed 'org.ow2.asm:asm-commons:8.0.1' embed 'org.ow2.asm:asm-commons:9.2'
embed 'com.google.code.gson:gson:2.8.7'
embed 'org.jetbrains.kotlin:kotlin-stdlib'
} }
jar { jar {
@ -45,3 +50,23 @@ gradlePlugin {
} }
} }
} }
publishing {
repositories {
maven {
url = file("/Users/sky/Desktop/repo")
}
}
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip distributionUrl=https://skymc.oss-cn-shanghai.aliyuncs.com/files/gradle-6.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

0
gradlew vendored Normal file → Executable file
View File

View File

@ -0,0 +1,42 @@
package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
class IsolatedAnnotationVisitor extends AnnotationVisitor {
String name
Project project
TabooLibClassVisitor parent
IsolatedAnnotationVisitor(AnnotationVisitor annotationVisitor, project, name, parent) {
super(Opcodes.ASM7, annotationVisitor)
this.name = name
this.project = project
this.parent = parent
this.parent.isolated[name] = new ArrayList<>()
}
@Override
AnnotationVisitor visitArray(String name) {
return new IsolatedExcludeAnnotationVisitor(super.visitArray(name), this)
}
class IsolatedExcludeAnnotationVisitor extends AnnotationVisitor {
IsolatedAnnotationVisitor parent
IsolatedExcludeAnnotationVisitor(AnnotationVisitor annotationVisitor, parent) {
super(Opcodes.ASM7, annotationVisitor)
this.parent = parent
}
@Override
void visit(String name, Object value) {
parent.parent.isolated[parent.name] += (value as Type).className
super.visit(name, value)
}
}
}

View File

@ -0,0 +1,55 @@
package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Opcodes
class KotlinAnnotationVisitor extends AnnotationVisitor {
Project project
KotlinAnnotationVisitor(AnnotationVisitor annotationVisitor, project) {
super(Opcodes.ASM7, annotationVisitor)
this.project = project
}
@Override
void visit(String name, Object value) {
if (value instanceof String) {
super.visit(name, value
.replace("@kotlin_version@", getKotlinVersion())
.replace("@kotlin_version_escape@", getKotlinVersionEscape())
)
} else {
super.visit(name, value)
}
}
@Override
void visitEnum(String name, String descriptor, String value) {
super.visitEnum(name, descriptor, value)
}
@Override
AnnotationVisitor visitAnnotation(String name, String descriptor) {
return new KotlinAnnotationVisitor(super.visitAnnotation(name, descriptor), project)
}
@Override
AnnotationVisitor visitArray(String name) {
return new KotlinAnnotationVisitor(super.visitArray(name), project)
}
@Override
void visitEnd() {
super.visitEnd()
}
String getKotlinVersion() {
return project.plugins.findPlugin("org.jetbrains.kotlin.jvm").kotlinPluginVersion
}
String getKotlinVersionEscape() {
return getKotlinVersion().replaceAll("[._-]", "")
}
}

View File

@ -0,0 +1,29 @@
package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Opcodes
class KotlinMetaAnnotationVisitor extends AnnotationVisitor {
Project project
KotlinMetaAnnotationVisitor(AnnotationVisitor annotationVisitor, project) {
super(Opcodes.ASM7, annotationVisitor)
this.project = project
}
@Override
void visit(String name, Object value) {
if (value instanceof String) {
super.visit(name, value.replace("taboolib", "${project.group.replace('.', '/')}/taboolib"))
} else {
super.visit(name, value)
}
}
@Override
AnnotationVisitor visitArray(String name) {
return new KotlinMetaAnnotationVisitor(super.visitArray(name), project)
}
}

View File

@ -0,0 +1,17 @@
package io.izzel.taboolib.gradle
import groovy.transform.EqualsAndHashCode
import groovy.transform.TupleConstructor
@TupleConstructor
@EqualsAndHashCode
class MethodVisit {
String owner
String name
@Override
String toString() {
return owner.substring(owner.lastIndexOf("/") + 1) + "." + name + "()"
}
}

View File

@ -4,12 +4,13 @@ import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
class SpongeAnnotationVisitor extends AnnotationVisitor { class PluginAnnotationVisitor extends AnnotationVisitor {
Project project Project project
SpongeAnnotationVisitor(AnnotationVisitor annotationVisitor) { PluginAnnotationVisitor(AnnotationVisitor annotationVisitor, project) {
super(Opcodes.ASM5, annotationVisitor) super(Opcodes.ASM7, annotationVisitor)
this.project = project
} }
@Override @Override

View File

@ -1,7 +1,9 @@
package io.izzel.taboolib.gradle package io.izzel.taboolib.gradle
import groovy.transform.ToString import groovy.transform.ToString
import io.izzel.taboolib.gradle.description.Platforms
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional import org.gradle.api.tasks.Optional
@ -15,6 +17,8 @@ import java.nio.file.StandardCopyOption
import java.util.jar.JarEntry import java.util.jar.JarEntry
import java.util.jar.JarFile import java.util.jar.JarFile
import java.util.jar.JarOutputStream import java.util.jar.JarOutputStream
import java.util.stream.Collectors
import java.util.zip.ZipException
@ToString @ToString
class RelocateJar extends DefaultTask { class RelocateJar extends DefaultTask {
@ -29,39 +33,204 @@ class RelocateJar extends DefaultTask {
@Input @Input
String classifier String classifier
@Input
Project project
@Input
TabooLibExtension tabooExt
@TaskAction @TaskAction
def relocate() { def relocate() {
//
def optimize = []
def isolated = new TreeMap<String, List<String>>()
def methodVisits = new TreeMap<String, Set<MethodVisit>>()
//
def mapping = relocations.collectEntries { [(it.key.replace('.', '/')), it.value.replace('.', '/')] } def mapping = relocations.collectEntries { [(it.key.replace('.', '/')), it.value.replace('.', '/')] }
def remapper = new RelocateRemapper(relocations, mapping as Map<String, String>) def remapper = new RelocateRemapper(relocations, mapping as Map<String, String>)
//
def index = inJar.name.lastIndexOf('.') def index = inJar.name.lastIndexOf('.')
def name = inJar.name.substring(0, index) + (classifier == null ? "" : "-" + classifier) + inJar.name.substring(index) def name = inJar.name.substring(0, index) + (classifier == null ? "" : "-" + classifier) + inJar.name.substring(index)
def outJar = new File(inJar.getParentFile(), name) def outJar = new File(inJar.getParentFile(), name)
def tmpOut = File.createTempFile(name, ".jar") def tempOut1 = File.createTempFile(name, ".jar")
new JarOutputStream(new FileOutputStream(tmpOut)).withCloseable { out ->
project.logger.info(outJar.getAbsolutePath()) //
new JarOutputStream(new FileOutputStream(tempOut1)).withCloseable { out ->
int n int n
def buf = new byte[32768] def buf = new byte[32768]
new JarFile(inJar).withCloseable { jarFile -> new JarFile(inJar).withCloseable { jarFile ->
for (def jarEntry : jarFile.entries()) { jarFile.entries().each { JarEntry jarEntry ->
def path = jarEntry.name
//
if (tabooExt.exclude.stream().any { String e -> path.startsWith(e) }) {
return
}
//
if (path.endsWith(".kotlin_module")) {
return
}
//
if (path.startsWith("META-INF/tf") && path.endsWith(".json")) {
optimize.add(Bridge.newOptimizeFileReader(project, jarFile.getInputStream(jarEntry)))
return
}
// Kotlin
def options = tabooExt.options
if (path == "taboolib/common/env/KotlinEnv.class" && options.contains("skip-kotlin")) {
return
}
//
if (path.startsWith("taboolib/common/env") && options.contains("skip-env")) {
return
}
// common
if (path.startsWith("taboolib/library/asm") || path.startsWith("taboolib/library/jarrelocator")) {
if (options.contains("skip-env") || options.contains("skip-env-relocate")) {
return
}
}
jarFile.getInputStream(jarEntry).withCloseable { jarFile.getInputStream(jarEntry).withCloseable {
if (jarEntry.name.endsWith(".class")) { if (path.endsWith(".class")) {
project.logger.info("Relocating " + jarEntry.name)
def reader = new ClassReader(it) def reader = new ClassReader(it)
def writer = new ClassWriter(0) def writer = new ClassWriter(0)
def visitor = new TabooLibClassVisitor(writer) def visitor = new TabooLibClassVisitor(writer, project)
reader.accept(new ClassRemapper(visitor, remapper), 0) def rem = new ClassRemapper(visitor, remapper)
out.putNextEntry(new JarEntry(remapper.map(jarEntry.name))) remapper.remapper = rem
reader.accept(rem, 0)
//
isolated.putAll(visitor.isolated)
// 访
methodVisits.put(relocate(project, jarEntry.name), visitor.methodVisits)
//
//
try {
out.putNextEntry(new JarEntry(remapper.map(path)))
} catch (ZipException zipException) {
println(zipException)
return true
}
out.write(writer.toByteArray()) out.write(writer.toByteArray())
} else { } else {
out.putNextEntry(new JarEntry(remapper.map(jarEntry.name))) try {
out.putNextEntry(new JarEntry(remapper.map(path)))
} catch (ZipException ex) {
println(ex)
return true
}
while ((n = it.read(buf)) != -1) {
out.write(buf, 0, n)
}
}
null
}
}
}
}
//
// -> 使
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 visits = methodVisits[methodVisits.keySet().first()]
if (visits != null) {
visits.each {
println(it)
}
}
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 { JarEntry jarEntry ->
if (optimize.any { it.exclude(jarEntry.name, use) }) {
return
}
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)) {
del.add(nameWithOutExtension)
}
}
}
if (!del.contains(getNameWithOutExtension(jarEntry.name))) {
out.putNextEntry(new JarEntry(jarEntry.name))
while ((n = it.read(buf)) != -1) { while ((n = it.read(buf)) != -1) {
out.write(buf, 0, n) out.write(buf, 0, n)
} }
} }
} }
} }
Platforms.values().each {
if (tabooExt.modules.contains(it.module)) {
out.putNextEntry(new JarEntry(it.file))
out.write(it.builder.build(tabooExt.des, project))
} }
} }
Files.copy(tmpOut.toPath(), outJar.toPath(), StandardCopyOption.REPLACE_EXISTING) }
}
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 name,
String exclude = null
) {
if (isolated.containsKey(name)) {
return refer.size() <= 1 || refer.stream()
.filter { it != exclude }
.allMatch {
name == it || isolated[name].contains(it) || isIsolated(use, use[it], isolated, it, name)
}
} else {
return false
}
}
@Override
public String toString() {
return "RelocateJar{}";
} }
} }

View File

@ -1,6 +1,7 @@
package io.izzel.taboolib.gradle package io.izzel.taboolib.gradle
import groovy.transform.Canonical import groovy.transform.Canonical
import org.objectweb.asm.commons.ClassRemapper
import org.objectweb.asm.commons.Remapper import org.objectweb.asm.commons.Remapper
@Canonical @Canonical
@ -8,6 +9,8 @@ class RelocateRemapper extends Remapper {
Map<String, String> dot Map<String, String> dot
Map<String, String> slash Map<String, String> slash
Map<String, Set<String>> use = new TreeMap()
ClassRemapper remapper
@Override @Override
Object mapValue(Object value) { Object mapValue(Object value) {
@ -20,8 +23,15 @@ class RelocateRemapper extends Remapper {
return super.mapValue(value) return super.mapValue(value)
} }
@SuppressWarnings('GroovyAccessibility')
@Override @Override
String map(String internalName) { String map(String internalName) {
if (remapper != null) {
use.computeIfAbsent(remapper.className) { new HashSet() }.add(internalName)
}
if (internalName.startsWith('kotlin/Metadata')) {
return internalName
}
def match = slash.find { internalName.startsWith(it.key) } def match = slash.find { internalName.startsWith(it.key) }
if (match) { if (match) {
return match.value + internalName.substring(match.key.length()) return match.value + internalName.substring(match.key.length())

View File

@ -1,21 +1,62 @@
package io.izzel.taboolib.gradle package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassVisitor import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
class TabooLibClassVisitor extends ClassVisitor { class TabooLibClassVisitor extends ClassVisitor {
TabooLibClassVisitor(ClassVisitor classVisitor) { String name
super(Opcodes.ASM5, classVisitor);
Project project
Map<String, List<String>> isolated = new HashMap()
Set<MethodVisit> methodVisits = new HashSet<>()
List<String> annotations = [
"Lorg/spongepowered/api/plugin/Plugin;",
"Lorg/spongepowered/plugin/jvm/Plugin;",
"Lcom/velocitypowered/api/plugin/Plugin;"
]
TabooLibClassVisitor(ClassVisitor classVisitor, Project project) {
super(Opcodes.ASM7, classVisitor);
this.project = project
}
@Override
void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.name = name
super.visit(version, access, name, signature, superName, interfaces)
}
@Override
MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return new TabooLibMethodVisitor(super.visitMethod(access, name, descriptor, signature, exceptions), this)
} }
@Override @Override
AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
if (descriptor == "Lorg/spongepowered/api/plugin/Plugin;") { if (descriptor == "Lkotlin/Metadata;") {
return new SpongeAnnotationVisitor(super.visitAnnotation(descriptor, visible)) return new KotlinMetaAnnotationVisitor(super.visitAnnotation(descriptor, visible), project)
} else if (descriptor == "L${project.group.replace('.', '/')}/taboolib/common/Isolated;") {
return new IsolatedAnnotationVisitor(super.visitAnnotation(descriptor, visible), project, name, this)
} else if (descriptor == "L${project.group.replace('.', '/')}/taboolib/common/env/RuntimeDependency;") {
return new KotlinAnnotationVisitor(super.visitAnnotation(descriptor, visible), project)
} else if (descriptor == "L${project.group.replace('.', '/')}/taboolib/common/env/RuntimeDependencies;") {
return new KotlinAnnotationVisitor(super.visitAnnotation(descriptor, visible), project)
} else if (descriptor in annotations) {
return new PluginAnnotationVisitor(super.visitAnnotation(descriptor, visible), project)
} else { } else {
return super.visitAnnotation(descriptor, visible) return super.visitAnnotation(descriptor, visible)
} }
} }
@Override
void visitEnd() {
super.visitEnd()
}
} }

View File

@ -1,6 +1,8 @@
package io.izzel.taboolib.gradle package io.izzel.taboolib.gradle
import groovy.transform.Canonical import groovy.transform.Canonical
import io.izzel.taboolib.gradle.description.Description
import org.gradle.api.Action
@Canonical @Canonical
class TabooLibExtension { class TabooLibExtension {
@ -9,15 +11,33 @@ class TabooLibExtension {
String classifier = "all" String classifier = "all"
List<String> modules = new ArrayList<>(); List<String> modules = []
List<String> exclude = []
Description des = new Description()
Map<String, String> relocation = new LinkedHashMap<>() Map<String, String> relocation = new LinkedHashMap<>()
List<String> options = []
def install(String... name) { def install(String... name) {
name.each { modules += it } name.each { modules += it }
} }
def options(String... opt) {
opt.each { options += it }
}
def exclude(String match) {
exclude += match
}
def relocate(String pre, String post) { def relocate(String pre, String post) {
relocation[pre] = post relocation[pre] = post
} }
def description(Action<? super Description> action) {
action.execute(des)
}
} }

View File

@ -0,0 +1,183 @@
package io.izzel.taboolib.gradle
import groovy.transform.EqualsAndHashCode
import groovy.transform.TupleConstructor
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Attribute
import org.objectweb.asm.Handle
import org.objectweb.asm.Label
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.TypePath
class TabooLibMethodVisitor extends MethodVisitor {
TabooLibClassVisitor classVisitor
TabooLibMethodVisitor(MethodVisitor methodVisitor, TabooLibClassVisitor classVisitor) {
super(Opcodes.ASM7, methodVisitor)
this.classVisitor = classVisitor
}
@Override
void visitParameter(String name, int access) {
super.visitParameter(name, access)
}
@Override
AnnotationVisitor visitAnnotationDefault() {
return super.visitAnnotationDefault()
}
@Override
AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return super.visitAnnotation(descriptor, visible)
}
@Override
AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
}
@Override
void visitAnnotableParameterCount(int parameterCount, boolean visible) {
super.visitAnnotableParameterCount(parameterCount, visible)
}
@Override
AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) {
return super.visitParameterAnnotation(parameter, descriptor, visible)
}
@Override
void visitAttribute(Attribute attribute) {
super.visitAttribute(attribute)
}
@Override
void visitCode() {
super.visitCode()
}
@Override
void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) {
super.visitFrame(type, numLocal, local, numStack, stack)
}
@Override
void visitInsn(int opcode) {
super.visitInsn(opcode)
}
@Override
void visitIntInsn(int opcode, int operand) {
super.visitIntInsn(opcode, operand)
}
@Override
void visitVarInsn(int opcode, int i) {
super.visitVarInsn(opcode, i)
}
@Override
void visitTypeInsn(int opcode, String type) {
super.visitTypeInsn(opcode, type)
}
@Override
void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
super.visitFieldInsn(opcode, owner, name, descriptor)
}
@Override
void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
super.visitMethodInsn(opcode, owner, name, descriptor)
}
@Override
void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
classVisitor.methodVisits.add(new MethodVisit(owner, name))
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
}
@Override
void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
}
@Override
void visitJumpInsn(int opcode, Label label) {
super.visitJumpInsn(opcode, label)
}
@Override
void visitLabel(Label label) {
super.visitLabel(label)
}
@Override
void visitLdcInsn(Object value) {
super.visitLdcInsn(value)
}
@Override
void visitIincInsn(int i, int increment) {
super.visitIincInsn(i, increment)
}
@Override
void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
super.visitTableSwitchInsn(min, max, dflt, labels)
}
@Override
void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
super.visitLookupSwitchInsn(dflt, keys, labels)
}
@Override
void visitMultiANewArrayInsn(String descriptor, int numDimensions) {
super.visitMultiANewArrayInsn(descriptor, numDimensions)
}
@Override
AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible)
}
@Override
void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
super.visitTryCatchBlock(start, end, handler, type)
}
@Override
AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible)
}
@Override
void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
super.visitLocalVariable(name, descriptor, signature, start, end, index)
}
@Override
AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) {
return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible)
}
@Override
void visitLineNumber(int line, Label start) {
super.visitLineNumber(line, start)
}
@Override
void visitMaxs(int maxStack, int maxLocals) {
super.visitMaxs(maxStack, maxLocals)
}
@Override
void visitEnd() {
super.visitEnd()
}
}

View File

@ -8,28 +8,32 @@ class TabooLibPlugin implements Plugin<Project> {
@Override @Override
void apply(Project project) { void apply(Project project) {
project.repositories.maven { url URI("https://repo2s.ptms.ink/repository/maven-releases/") } project.repositories.maven { url project.uri("https://repo2s.ptms.ink/repository/maven-releases/") }
def tabooExt = project.extensions.create('taboolib', TabooLibExtension) def tabooExt = project.extensions.create('taboolib', TabooLibExtension)
def taboo = project.configurations.maybeCreate('taboo') def taboo = project.configurations.maybeCreate('taboo')
def tabooTask = project.tasks.create('tabooRelocateJar', RelocateJar) def tabooTask = project.tasks.create('tabooRelocateJar', RelocateJar)
tabooTask.project = project
project.afterEvaluate { project.afterEvaluate {
project.configurations.compileClasspath.extendsFrom(taboo) project.configurations.compileClasspath.extendsFrom(taboo)
// subprojects // subprojects
tabooExt.modules.each { tabooExt.modules.each {
project.configurations.compileClasspath.dependencies.add(project.dependencies.create("io.izzel:taboolib:${tabooExt.version}:${it}")) project.configurations.taboo.dependencies.add(project.dependencies.create("io.izzel:taboolib:${tabooExt.version}:${it}"))
} }
project.tasks.jar.finalizedBy(tabooTask) project.tasks.jar.finalizedBy(tabooTask)
project.tasks.jar.configure { Jar task -> project.tasks.jar.configure { Jar task ->
task.from(taboo.collect { it.isDirectory() ? it : project.zipTree(it) }) task.from(taboo.collect { it.isDirectory() ? it : project.zipTree(it) })
} }
def kv = project.plugins.findPlugin("org.jetbrains.kotlin.jvm").kotlinPluginVersion.replaceAll("[._-]", "")
def jarTask = project.tasks.jar as Jar def jarTask = project.tasks.jar as Jar
tabooTask.configure { RelocateJar task -> tabooTask.configure { RelocateJar task ->
task.tabooExt = tabooExt
task.project = project
task.inJar = task.inJar ?: jarTask.archivePath task.inJar = task.inJar ?: jarTask.archivePath
task.relocations = tabooExt.relocation task.relocations = tabooExt.relocation
task.classifier = tabooExt.classifier task.classifier = tabooExt.classifier
task.relocations['taboolib'] = task.relocations['taboolib'] ?: project.group.toString() + '.taboolib' task.relocations['taboolib'] = project.group.toString() + '.taboolib'
if (!tabooExt.options.contains("skip-kotlin") && !tabooExt.options.contains("skip-kotlin-relocate")) {
task.relocations['kotlin.'] = 'kotlin' + kv + '.'
}
} }
} }
} }

View File

@ -0,0 +1,75 @@
package io.izzel.taboolib.gradle.description
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import org.gradle.api.Project
import java.nio.charset.StandardCharsets
abstract class Builder {
abstract byte[] build(Description description, Project project)
static List<String> startBukkitFile() {
def str = []
str += ''
str += ''
str += '# Powered by TabooLib 6.0 #'
str += ''
str += ''
return str
}
static def writeLine(body) {
body.add("")
}
static def write(List<String> body, data, key) {
if (data != null) {
body.add("$key: $data")
}
}
static def write(JsonObject body, data, key) {
if (data != null) {
body.addProperty("$key", "$data")
}
}
static def writeList(List<String> body, data, key) {
if (data instanceof List<String>) {
if (data.size() > 0) {
body.add("$key:")
for (i in data) {
body.add(" - '${i}'")
}
}
} else if (data != null) {
body.add("$key:")
body.add(" - '${data}'")
}
}
static def writeList(JsonObject body, data, key) {
def arr = new JsonArray()
if (data instanceof List<String>) {
if (data.size() > 0) {
data.each { arr.add(it) }
body.add(key, arr)
}
} else if (data != null) {
arr.add(data.toString())
body.add(key, arr)
}
}
static byte[] bytes(List<String> body) {
return body.join('\n').getBytes(StandardCharsets.UTF_8)
}
static byte[] bytes(JsonElement body) {
return new GsonBuilder().setPrettyPrinting().create().toJson(body).getBytes(StandardCharsets.UTF_8)
}
}

View File

@ -0,0 +1,43 @@
package io.izzel.taboolib.gradle.description
import org.gradle.api.Project
class BuilderBukkit extends Builder {
@Override
byte[] build(Description description, Project project) {
def body = startBukkitFile()
body += "name: ${project.name}"
body += "main: ${project.group}.taboolib.platform.BukkitPlugin"
body += "version: ${project.version}"
write(body, description.lin.links['homepage'], 'website')
writeLine(body)
// authors
def con = description.con.contributors.collect { it.name }
writeList(body, con, 'authors')
writeLine(body)
// dependency
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('bukkit') }
.findAll { it.forceDepend() }
.collect { it.name }, 'depend')
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('bukkit') }
.findAll { it.optional }
.collect { it.name }, 'softdepend')
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('bukkit') }
.findAll { it.loadbefore }
.collect { it.name }, 'loadbefore')
writeLine(body)
// custom nodes
description.bukkitNodes.each {
if (it.value instanceof List) {
writeList(body, it.value, it.key)
} else {
write(body, it.value, it.key)
}
}
return bytes(body)
}
}

View File

@ -0,0 +1,39 @@
package io.izzel.taboolib.gradle.description
import org.gradle.api.Project
class BuilderBungee extends Builder {
@Override
byte[] build(Description description, Project project) {
def body = startBukkitFile()
body += "name: ${project.name}"
body += "main: ${project.group}.taboolib.platform.BungeePlugin"
body += "version: ${project.version}"
write(body, description.lin.links['homepage'], 'website')
writeLine(body)
// authors
def con = description.con.contributors.collect { it.name }.join(', ')
write(body, con, 'author')
writeLine(body)
// dependency
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('bungee') }
.findAll { it.forceDepend() }
.collect { it.name }, 'depends')
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('bungee') }
.findAll { it.optional }
.collect { it.name }, 'softDepends')
writeLine(body)
// custom nodes
description.bungeeNodes.each {
if (it.value instanceof List) {
writeList(body, it.value, it.key)
} else {
write(body, it.value, it.key)
}
}
return bytes(body)
}
}

View File

@ -0,0 +1,43 @@
package io.izzel.taboolib.gradle.description
import org.gradle.api.Project
class BuilderNukkit extends Builder {
@Override
byte[] build(Description description, Project project) {
def body = startBukkitFile()
body += "name: ${project.name}"
body += "main: ${project.group}.taboolib.platform.NukkitPlugin"
body += "version: ${project.version}"
write(body, description.lin.links['homepage'], 'website')
writeLine(body)
// authors
def con = description.con.contributors.collect { it.name }
writeList(body, con, 'authors')
writeLine(body)
// dependency
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('nukkit') }
.findAll { it.forceDepend() }
.collect { it.name }, 'depend')
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('nukkit') }
.findAll { it.optional }
.collect { it.name }, 'softdepend')
writeList(body, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('nukkit') }
.findAll { it.loadbefore }
.collect { it.name }, 'loadbefore')
writeLine(body)
// custom nodes
description.nukkitNodes.each {
if (it.value instanceof List) {
writeList(body, it.value, it.key)
} else {
write(body, it.value, it.key)
}
}
return bytes(body)
}
}

View File

@ -0,0 +1,33 @@
package io.izzel.taboolib.gradle.description
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import org.gradle.api.Project
class BuilderSponge7 extends Builder {
@Override
byte[] build(Description description, Project project) {
def json = new JsonArray()
def info = new JsonObject()
info.addProperty('modid', project.name.toLowerCase())
info.addProperty('name', project.name)
info.addProperty('version', project.version.toString())
write(info, description.spongeDesc, 'description')
write(info, description.lin.links['homepage'], 'url')
// authors
def con = description.con.contributors.collect { it.name }
writeList(info, con, 'authorList')
// dependencies
writeList(info, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('sponge7') }
.findAll { !it.mod }
.collect { it.fullyName() }, 'dependencies')
writeList(info, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('sponge7') }
.findAll { it.mod }
.collect { it.fullyName() }, 'requiredMods')
json.add(info)
return bytes(json)
}
}

View File

@ -0,0 +1,56 @@
package io.izzel.taboolib.gradle.description
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import org.gradle.api.Project
class BuilderSponge8 extends Builder {
@Override
byte[] build(Description description, Project project) {
def json = new JsonObject()
def plugins = new JsonArray()
def info = new JsonObject()
info.addProperty('loader', 'java_plain')
info.addProperty('id', project.name.toLowerCase())
info.addProperty('name', project.name)
info.addProperty('version', project.version.toString())
info.addProperty('main-class', "${project.group}.taboolib.platform.Sponge8Plugin")
write(info, description.spongeDesc, 'description')
// links
if (description.lin.links.size() > 0) {
def links = new JsonObject()
description.lin.links.each {
links.addProperty(it.key, it.value.url)
}
info.add('links', links)
}
// contributors
if (description.con.contributors.size() > 0) {
def contributors = new JsonArray()
description.con.contributors.each {
def con = new JsonObject()
write(con, it.name, 'name')
write(con, it.description, 'description')
contributors.add(con)
}
info.add('contributors', contributors)
}
// dependencies
if (description.dep.dependencies.size() > 0) {
def dependencies = new JsonArray()
description.dep.dependencies.findAll { it.with == null || it.with.equalsIgnoreCase('sponge8') }.each {
def dep = new JsonObject()
write(dep, it.name, 'id')
write(dep, it.version, 'version')
dep.addProperty('load-order', it.loadafter ? 'AFTER' : 'UNDEFINED')
dep.addProperty('optional', it.optional)
dependencies.add(dep)
}
info.add('dependencies', dependencies)
}
plugins.add(info)
json.add('plugins', plugins)
return bytes(json)
}
}

View File

@ -0,0 +1,25 @@
package io.izzel.taboolib.gradle.description
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import org.gradle.api.Project
class BuilderVelocity extends Builder {
@Override
byte[] build(Description description, Project project) {
def info = new JsonObject()
info.addProperty('id', project.name.toLowerCase())
info.addProperty('name', project.name)
info.addProperty('main', "${project.group}.taboolib.platform.VelocityPlugin")
info.addProperty('version', project.version.toString())
// authors
def con = description.con.contributors.collect { it.name }
writeList(info, con, 'authors')
// dependencies
writeList(info, description.dep.dependencies
.findAll { it.with == null || it.with.equalsIgnoreCase('velocity') }
.collect { it.name }, 'dependencies')
return bytes(info)
}
}

View File

@ -0,0 +1,27 @@
package io.izzel.taboolib.gradle.description
class Contributors {
List<Contributor> contributors = []
Contributor name(name) {
def con = new Contributor(name)
contributors += con
return con
}
class Contributor {
def name
def description
Contributor(name) {
this.name = name
}
Contributor description(description) {
this.description = description
return this
}
}
}

View File

@ -0,0 +1,66 @@
package io.izzel.taboolib.gradle.description
class Dependencies {
List<Dependency> dependencies = []
Dependency name(name) {
def dep = new Dependency(name)
dependencies += dep
return dep
}
class Dependency {
String name
String with
String version
def loadafter = false
def loadbefore = false
def optional = false
def mod = false
Dependency(name) {
this.name = name
}
def fullyName(spec = '@') {
return version == null ? name : name + spec + version
}
def forceDepend() {
return !loadafter && !loadbefore && !optional
}
Dependency with(description) {
this.with = description
return this
}
Dependency version(version) {
this.version = version
return this
}
Dependency loadafter(loadafter) {
this.loadafter = loadafter
return this
}
Dependency loadbefore(loadbefore) {
this.loadbefore = loadbefore
return this
}
Dependency optional(optional) {
this.optional = optional
return this
}
Dependency mod(mod) {
this.mod = mod
return this
}
}
}

View File

@ -0,0 +1,62 @@
package io.izzel.taboolib.gradle.description
import org.gradle.api.Action
class Description {
Contributors con = new Contributors()
Dependencies dep = new Dependencies()
Links lin = new Links()
def bukkitNodes = new HashMap()
def nukkitNodes = new HashMap()
def bungeeNodes = new HashMap()
String spongeDesc
Description() {
bukkitApi('1.13')
nukkitApi('1.0.0')
}
def desc(desc) {
bukkitNodes['description'] = desc
nukkitNodes['description'] = desc
bungeeNodes['description'] = desc
spongeDesc = desc
}
def load(order) {
bukkitNodes['load'] = order
nukkitNodes['load'] = order
}
def bukkitApi(api) {
bukkitNodes['api-version'] = api
}
def nukkitApi(api) {
nukkitNodes['api'] = api
}
def prefix(prefix) {
bukkitNodes['prefix'] = prefix
nukkitNodes['prefix'] = prefix
}
def contributors(Action<? super Contributors> action) {
action.execute(con)
}
def dependencies(Action<? super Dependencies> action) {
action.execute(dep)
}
def links(Action<? super Links> action) {
action.execute(lin)
}
}

View File

@ -0,0 +1,32 @@
package io.izzel.taboolib.gradle.description
class Links {
def links = new HashMap<String, Link>()
Link name(name) {
def link = new Link(name)
links[link.name] = link
return link
}
class Link {
String name
String url
Link(name) {
this.name = name
}
Link url(url) {
this.url = url
return this
}
@Override
String toString() {
return url
}
}
}

View File

@ -0,0 +1,28 @@
package io.izzel.taboolib.gradle.description
enum Platforms {
BUKKIT('Bukkit', 'platform-bukkit', 'plugin.yml', new BuilderBukkit()),
NUKKIT('Nukkit', 'platform-nukkit', 'nukkit.yml', new BuilderNukkit()),
BUNGEE('Bungee', 'platform-bungee', 'bungee.yml', new BuilderBungee()),
VELOCITY('Velocity', 'platform-velocity', 'velocity-plugin.json', new BuilderVelocity()),
SPONGE7('Sponge7', 'platform-sponge-api7', 'mcmod.info', new BuilderSponge7()),
SPONGE8('Sponge8', 'platform-sponge-api8', 'META-INF/plugins.json', new BuilderSponge8());
String key
String module
String file
Builder builder
Platforms(key, module, file, builder) {
this.key = key
this.module = module
this.file = file
this.builder = builder
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.taboolib.gradle;
import org.gradle.api.Project;
import java.io.InputStream;
/**
* taboolib-gradle-plugin
* io.izzel.taboolib.gradle.KotlinFactory
*
* @author sky
* @since 2021/8/14 1:43 下午
*/
public class Bridge {
public static OptimizeFileReader newOptimizeFileReader(Project project, InputStream inputStream) {
return new OptimizeFileReader(project, inputStream);
}
}

View File

@ -0,0 +1,134 @@
package io.izzel.taboolib.gradle
import com.google.gson.JsonParser
import org.gradle.api.Project
import java.io.InputStream
import java.nio.charset.StandardCharsets
/**
* taboolib-gradle-plugin
* io.izzel.taboolib.gradle.OptimizeFileReader
*
* @author sky
* @since 2021/8/14 1:18 下午
*/
class OptimizeFileReader(project: Project, input: InputStream) {
val optimize = ArrayList<Optimize>()
val group = ArrayList<Group>()
val exclude = ArrayList<String>()
init {
try {
val jsonSource = input.readBytes().toString(StandardCharsets.UTF_8)
val json = JsonParser.parseString(jsonSource).asJsonObject
if (json.has("optimize")) {
json.getAsJsonArray("optimize").forEach { ele ->
optimize += Optimize(
relocate(project, ele.asJsonObject["class"].asString),
Optimize.Type.valueOf(ele.asJsonObject["type"].asString)
)
}
}
if (json.has("group")) {
json.getAsJsonArray("group").forEach { ele ->
var depend: Group.Depend? = null
if (ele.asJsonObject.has("depend")) {
depend = Group.Depend(
ele.asJsonObject["depend"].asJsonObject["name"].asJsonArray.map { relocate(project, it.asString) },
ele.asJsonObject["depend"].asJsonObject["exclude"].asJsonArray.map { relocate(project, it.asString) }
)
}
group += Group(
ele.asJsonObject["check"].asJsonArray.map { relocate(project, it.asString) },
ele.asJsonObject["member"].asJsonArray.map { relocate(project, it.asString) },
ele.asJsonObject["exclude"]?.asJsonArray?.map { relocate(project, it.asString) }?.toList() ?: emptyList(),
depend,
Group.Mode.valueOf(ele.asJsonObject["mode"].asString)
)
}
}
if (json.has("exclude")) {
exclude += json.getAsJsonArray("exclude").map { relocate(project, it.asString) }
}
} catch (ex: Throwable) {
ex.printStackTrace()
}
}
fun relocate(project: Project, name: String): String {
return if (name.startsWith("taboolib")) {
project.group.toString().replace('.', '/') + '/' + name.replace('.', '/')
} else {
name.replace('.', '/')
}
}
fun exclude(name: String, use: Map<String, Set<String>>): Boolean {
if (exclude.any { name.startsWith(it) }) {
return true
}
if (group.any { it.exclude(name, use) }) {
return true
}
return false
}
class Optimize(val path: String, val type: Type) {
enum class Type {
METHOD
}
}
class Group(check: List<String>, member: List<String>, exclude: List<String>, val depend: Depend? = null, val mode: Mode) {
val check = check.platformFlatten()
val member = member.platformFlatten()
val exclude = exclude.platformFlatten()
class Depend(name: List<String>, exclude: List<String>) {
val name = name.platformFlatten()
val exclude = exclude.platformFlatten()
}
enum class Mode {
REMOVE
}
fun exclude(name: String, use: Map<String, Set<String>>): Boolean {
if (member.any { name.startsWith(it) }) {
if (depend != null) {
val fail = depend.name.any { n ->
val set = use[n]?.toMutableList() ?: ArrayList()
set.remove(n)
set.removeAll(depend.exclude)
set.isNotEmpty()
}
if (fail) {
return false
}
}
for (s in check) {
val set = use[s]?.toMutableList() ?: ArrayList()
set.remove(s)
set.removeAll(check)
set.removeAll(member)
set.removeAll(exclude)
if (set.isNotEmpty()) {
return false
}
}
return true
} else {
return false
}
}
}
}

View File

@ -0,0 +1,13 @@
package io.izzel.taboolib.gradle
val platforms = listOf("Bukkit", "Nukkit", "Bungee", "Sponge7", "Sponge8", "Velocity")
fun List<String>.platformFlatten(): List<String> {
return flatMap {
if (it.contains("{platform}")) {
platforms.map { p -> it.replace("{platform}", p) }
} else {
listOf(it)
}
}
}