Compare commits

...

35 Commits
1.3 ... 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
sky 7e76f33f13 1.4 2021-06-27 15:46:10 +08:00
29 changed files with 1398 additions and 46 deletions

View File

@ -1,11 +1,15 @@
plugins { plugins {
id 'groovy' id 'groovy'
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.3' version '1.27'
configurations { configurations {
embed embed
@ -20,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 {
@ -44,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

@ -0,0 +1,48 @@
package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Opcodes
class PluginAnnotationVisitor extends AnnotationVisitor {
Project project
PluginAnnotationVisitor(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("@plugin_id@", project.name.toLowerCase())
.replace("@plugin_name@", project.name)
.replace("@plugin_version@", project.version.toString())
)
} 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 super.visitAnnotation(name, descriptor)
}
@Override
AnnotationVisitor visitArray(String name) {
return super.visitArray(name)
}
@Override
void visitEnd() {
super.visitEnd()
}
}

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
@ -11,11 +13,12 @@ import org.objectweb.asm.ClassWriter
import org.objectweb.asm.commons.ClassRemapper import org.objectweb.asm.commons.ClassRemapper
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardCopyOption 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 {
@ -30,38 +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)
reader.accept(new ClassRemapper(writer, remapper), 0) def visitor = new TabooLibClassVisitor(writer, project)
out.putNextEntry(new JarEntry(remapper.map(jarEntry.name))) def rem = new ClassRemapper(visitor, remapper)
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

@ -0,0 +1,62 @@
package io.izzel.taboolib.gradle
import org.gradle.api.Project
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
class TabooLibClassVisitor extends ClassVisitor {
String name
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
AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
if (descriptor == "Lkotlin/Metadata;") {
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 {
return super.visitAnnotation(descriptor, visible)
}
}
@Override
void visitEnd() {
super.visitEnd()
}
}

View File

@ -1,21 +1,43 @@
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 {
String tabooLibVersion = '5.+' String version = '6.0.0'
String loaderVersion = '2.+' String classifier = "all"
String classifier = 'all' List<String> modules = []
boolean builtin = true 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) {
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) {
this.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,37 +8,31 @@ class TabooLibPlugin implements Plugin<Project> {
@Override @Override
void apply(Project project) { void apply(Project project) {
project.repositories.maven { url "http://repo.ptms.ink/repository/codemc-nms/" } project.repositories.maven { url project.uri("https://repo2s.ptms.ink/repository/maven-releases/") }
project.repositories.maven { url "http://repo.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)
project.afterEvaluate { project.afterEvaluate {
project.configurations.compileClasspath.extendsFrom(taboo) project.configurations.compileClasspath.extendsFrom(taboo)
project.configurations.compileClasspath.dependencies.add(project.dependencies.create("io.izzel.taboolib:TabooLib:${tabooExt.tabooLibVersion}:all")) // subprojects
if (tabooExt.builtin) { tabooExt.modules.each {
taboo.dependencies.add(project.dependencies.create("io.izzel.taboolib:TabooLibLoader:${tabooExt.loaderVersion}:all")) project.configurations.taboo.dependencies.add(project.dependencies.create("io.izzel:taboolib:${tabooExt.version}:${it}"))
} }
def shadowPresent = project.plugins.hasPlugin('com.github.johnrengelman.shadow')
if (!shadowPresent) {
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['io.izzel.taboolib.loader'] = task.relocations['io.izzel.taboolib.loader'] ?: project.group.toString() + '.boot' task.relocations['taboolib'] = project.group.toString() + '.taboolib'
task.relocations['org.bstats.bukkit'] = task.relocations['org.bstats.bukkit'] ?: project.group.toString() + '.metrics' if (!tabooExt.options.contains("skip-kotlin") && !tabooExt.options.contains("skip-kotlin-relocate")) {
} task.relocations['kotlin.'] = 'kotlin' + kv + '.'
} else {
def shadowJar = project.tasks.getByName('shadowJar')
if (shadowJar) {
shadowJar.configurations.add(taboo)
} }
} }
} }

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)
}
}
}