Skip to content

Commit

Permalink
refactor libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
acrylic-style committed Nov 10, 2024
1 parent b8cc416 commit c54a1d1
Show file tree
Hide file tree
Showing 18 changed files with 290 additions and 146 deletions.
60 changes: 7 additions & 53 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import java.io.ByteArrayOutputStream

plugins {
kotlin("jvm") version "1.6.10"
kotlin("kapt") version "1.6.10"
id("com.github.johnrengelman.shadow") version "7.0.0"
kotlin("jvm") version "2.0.21"
id("com.gradleup.shadow") version "8.3.3"
`maven-publish`
`java-library`
}

group = "net.azisaba.spicyazisaban"
version = "0.3.0-${getBranch()}-${getGitHash()}${if (hasUncommittedChanges()) "-debug" else ""}"
version = "1.0.0-${getBranch()}-${getGitHash()}${if (hasUncommittedChanges()) "-debug" else ""}"

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
Expand All @@ -33,7 +32,7 @@ fun getGitHash(): String {
standardOutput = stdout
}
stdout.toString().trim()
} catch (e: Exception) {
} catch (_: Exception) {
val ref = file("./.git/HEAD").readText().replace("^.*: (.*)$".toRegex(), "$1").trim(' ', '\n')
println("Reading file ${file("./.git/$ref").absolutePath}")
file("./.git/$ref").readText().trim(' ', '\n').substring(0..7)
Expand All @@ -48,7 +47,7 @@ fun hasUncommittedChanges(): Boolean {
standardOutput = stdout
}
stdout.toString().trim().isNotBlank()
} catch (e: Exception) {
} catch (_: Exception) {
false
}
}
Expand Down Expand Up @@ -78,8 +77,7 @@ subprojects {

apply {
plugin("org.jetbrains.kotlin.jvm")
plugin("org.jetbrains.kotlin.kapt")
plugin("com.github.johnrengelman.shadow")
plugin("com.gradleup.shadow")
plugin("maven-publish")
plugin("java-library")
}
Expand All @@ -91,23 +89,12 @@ subprojects {
}

tasks {
compileKotlin {
kotlinOptions.jvmTarget = "17"
}

compileTestKotlin {
kotlinOptions.jvmTarget = "17"
}

test {
useJUnitPlatform()
}

kapt {
this.javacOptions { this.option("source", 17) }
}

processResources {
doNotTrackState("bungee.yml should be updated every time")
filteringCharset = "UTF-8"
from(sourceSets.main.get().resources.srcDirs) {
include("**")
Expand All @@ -121,18 +108,6 @@ subprojects {

filter<org.apache.tools.ant.filters.ReplaceTokens>("tokens" to tokenReplacementMap)
}
from(sourceSets.main.get().allSource.srcDirs) {
include("**")

val tokenReplacementMap = mapOf(
"version" to project.version,
"name" to project.rootProject.name,
"debugBuild" to hasUncommittedChanges().toString(),
"devBuild" to (getBranch() != "main").toString(),
)

filter<org.apache.tools.ant.filters.ReplaceTokens>("tokens" to tokenReplacementMap)
}

duplicatesStrategy = DuplicatesStrategy.INCLUDE

Expand Down Expand Up @@ -173,23 +148,6 @@ subprojects {
}

dependencies {
implementation("xyz.acrylicstyle.util:maven:0.16.6")
implementation("net.blueberrymc:native-util:2.1.0")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
implementation("xyz.acrylicstyle.util:all:0.16.6") {
exclude("com.google.guava", "guava")
exclude("org.reflections", "reflections")
exclude("org.json", "json")
exclude("org.yaml", "snakeyaml")
exclude("xyz.acrylicstyle.util", "maven")
}
implementation("xyz.acrylicstyle:sequelize4j:0.6.3") {
exclude("xyz.acrylicstyle", "java-util-all")
}
implementation("xyz.acrylicstyle:minecraft-util:1.0.0") {
exclude("xyz.acrylicstyle", "java-util-all")
}
compileOnly("org.mariadb.jdbc:mariadb-java-client:2.7.3")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
}
}
Expand Down Expand Up @@ -221,10 +179,6 @@ allprojects {
}
}

println("Deleting cached bungee.yml")
file("./build/resources/main/bungee.yml").apply {
if (exists()) delete()
}
println("Version: ${project.version}")
println("Debug build: ${hasUncommittedChanges()}")
println("Dev build: ${project.version.toString().contains("-dev")}")
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import net.azisaba.spicyAzisaBan.SpicyAzisaBan
import net.azisaba.spicyAzisaBan.bungee.listener.EventListeners
import net.azisaba.spicyAzisaBan.bungee.listener.LockdownListener
import net.azisaba.spicyAzisaBan.bungee.listener.PlayerDataUpdaterListener
import net.azisaba.spicyAzisaBan.remapper.JarUtils
import net.blueberrymc.nativeutil.NativeUtil
import net.md_5.bungee.api.plugin.Plugin
import util.maven.Dependency
import util.maven.JarUtils
import util.maven.MavenRepository
import util.maven.Repository
import org.eclipse.aether.util.graph.visitor.NodeListGenerator
import org.eclipse.aether.util.graph.visitor.PreorderDependencyNodeConsumerVisitor
import xyz.acrylicstyle.util.maven.MavenResolver
import java.io.File
import java.net.URLClassLoader
import java.util.logging.Logger
Expand All @@ -23,36 +23,29 @@ class BungeePlugin: Plugin() {
init {
val dataFolder = File("plugins/SpicyAzisaBan")
LOGGER.info("Data folder: ${dataFolder.absolutePath}")
val maven = MavenRepository()
maven.addRepository(Repository.mavenLocal())
maven.addRepository(Repository.mavenCentral())
maven.addDependency(Dependency.resolve('c' + "om.google.guava:guava:31.0.1-jre"))
maven.addDependency(Dependency.resolve("org.reflections:reflections:0.10.2"))
maven.addDependency(Dependency.resolve('o' + "rg.json:json:20210307"))
maven.addDependency(Dependency.resolve("org.yaml:snakeyaml:1.29"))
maven.addDependency(Dependency.resolve('o' + "rg.mariadb.jdbc:mariadb-java-client:2.7.3"))
maven.addExclude("log4j", "log4j")
var hasError = false
val files = maven.newFetcher(File(dataFolder, "libraries")).withMessageReporter { msg, throwable ->
if (throwable == null) {
LOGGER.info(msg)
} else {
LOGGER.warning(msg)
val nodeListGenerator = NodeListGenerator()
MavenResolver("plugins/SpicyAzisaBan/libraries")
.addMavenCentral()
.addDependency('c' + "om.google.guava:guava:31.0.1-jre")
.addDependency('o' + "rg.reflections:reflections:0.10.2")
.addDependency('o' + "rg.json:json:20210307")
.addDependency('o' + "rg.yaml:snakeyaml:1.29")
.addDependency('o' + "rg.mariadb.jdbc:mariadb-java-client:3.5.0")
.resolve { node, list -> node.artifact.groupId != "log4j" }
.forEach {
it.root.accept(PreorderDependencyNodeConsumerVisitor(nodeListGenerator))
}
throwable?.let {
hasError = true
it.printStackTrace()
}
}.downloadAllDependencies()
if (hasError) LOGGER.warning("Failed to download some dependencies.")
val cl = BungeePlugin::class.java.classLoader
val urls = files.filterNotNull()
.map { file -> JarUtils.remapJarWithClassPrefix(file, "-remapped", "net.azisaba.spicyAzisaBan.libs") }
.map { file -> file.toURI().toURL() }
val dedupe = nodeListGenerator.nodes.sortedByDescending { it.version }.distinctBy { it.artifact.groupId to it.artifact.artifactId }
nodeListGenerator.nodes.retainAll(dedupe)
val urls = nodeListGenerator.paths
.map { it.toFile() }
.map { JarUtils.remapJarWithClassPrefix(it, "-remapped", "net.azisaba.spicyAzisaBan.libs") }
.map { it.toURI().toURL() }
.toTypedArray()
val cl = BungeePlugin::class.java.classLoader
val libraryLoader = URLClassLoader(urls)
NativeUtil.setObject(cl::class.java.getDeclaredField("libraryLoader"), cl, libraryLoader)
LOGGER.info("Loaded libraries (" + files.size + "):")
LOGGER.info("Loaded libraries (" + urls.size + "):")
urls.forEach { url ->
LOGGER.info(" - ${url.path}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import net.azisaba.spicyAzisaBan.common.PlayerActor
import net.azisaba.spicyAzisaBan.common.ServerInfo
import net.azisaba.spicyAzisaBan.common.chat.Component
import net.azisaba.spicyAzisaBan.common.title.Title
import util.UUIDUtil
import java.net.SocketAddress
import java.util.UUID

Expand All @@ -26,7 +25,7 @@ object CLIActor: PlayerActor, Actor {
override fun isOnline(): Boolean = true

override val name: String = "CONSOLE"
override val uniqueId: UUID = UUIDUtil.NIL
override val uniqueId: UUID = UUID(0, 0)

override fun sendMessage(component: Component) {
println((component as SimpleComponent).getText())
Expand Down
21 changes: 20 additions & 1 deletion common/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
dependencies {
api("xyz.acrylicstyle.java-util:common:1.0.0-SNAPSHOT")
api("xyz.acrylicstyle.java-util:common:2.1.0")
api("xyz.acrylicstyle.java-util:maven:2.1.0")
api("net.blueberrymc:native-util:2.1.2")
api("org.jetbrains.kotlin:kotlin-stdlib:2.0.21")
api("xyz.acrylicstyle.util:all:0.16.6") {
exclude("com.google.guava", "guava")
exclude("org.reflections", "reflections")
exclude("org.json", "json")
exclude("org.yaml", "snakeyaml")
exclude("xyz.acrylicstyle.util", "maven")
}
api("xyz.acrylicstyle:sequelize4j:0.6.3") {
exclude("xyz.acrylicstyle", "java-util-all")
}
api("xyz.acrylicstyle:minecraft-util:1.0.0") {
exclude("xyz.acrylicstyle", "java-util-all")
}
api("org.ow2.asm:asm:9.7.1")
api("org.ow2.asm:asm-commons:9.7.1")
compileOnlyApi("org.mariadb.jdbc:mariadb-java-client:3.5.0")
}
140 changes: 140 additions & 0 deletions common/src/main/java/net/azisaba/spicyAzisaBan/remapper/JarUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@

package net.azisaba.spicyAzisaBan.remapper;

import com.google.common.io.ByteStreams;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class JarUtils {
/**
* Remap the class names.
* @param src source jar (zip) file
* @param fileSuffix suffix to apply to src file name.
* @param prefix class name prefix without trailing dot or slash
* @return destination file
* @throws IOException if an I/O error occurs
*/
@NotNull
public static File remapJarWithClassPrefix(@NotNull File src, @NotNull String fileSuffix, @NotNull String prefix) throws IOException {
return remapJarWithClassPrefix(src, fileSuffix, prefix, new PrefixClassRemapper(prefix));
}

/**
* Remap the class names.
* @param src source jar (zip) file
* @param fileSuffix suffix to apply to src file name.
* @param prefix class name prefix without trailing dot or slash
* @return destination file
* @throws IOException if an I/O error occurs
*/
@NotNull
public static File remapJarWithClassPrefix(@NotNull File src, @NotNull String fileSuffix, @NotNull String prefix, @NotNull Remapper remapper) throws IOException {
String[] split = src.getName().split("\\.");
StringBuilder name = new StringBuilder(split[0]);
for (int i = 1; i < split.length - 1; i++) name.append('.').append(split[i]);
String extension = "";
if (split.length > 1) extension = "." + split[split.length - 1];
File dst = new File(src.getParentFile(), name + fileSuffix + extension);
remapJarWithClassPrefix(src, dst, prefix, remapper);
return dst;
}

public static void remapJarWithClassPrefix(@NotNull File src, @NotNull File dst, @NotNull String prefix) throws IOException {
remapJarWithClassPrefix(src, dst, prefix, new PrefixClassRemapper(prefix));
}

public static void remapJarWithClassPrefix(@NotNull File src, @NotNull File dst, @NotNull String prefix, @NotNull Remapper remapper) throws IOException {
ZipFile zipFile = new ZipFile(src);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(dst));
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class")) {
out.putNextEntry(new ZipEntry(prefix.replace('.', '/') + '/' + entry.getName()));
byte[] bytes = remapClassWithClassPrefix(zipFile.getInputStream(entry), prefix, remapper);
ByteStreams.copy(new ByteArrayInputStream(bytes), out);
} else {
out.putNextEntry(new ZipEntry(entry.getName()));
if (entry.getName().equals("META-INF/MANIFEST.MF")) {
StringBuilder sb = new StringBuilder();
for (String line : readLines(zipFile.getInputStream(entry))) {
if (line.startsWith("#")) {
sb.append(line);
} else {
String[] split = line.split(": ");
if (split.length == 1) {
sb.append(split[0]);
} else {
sb.append(split[0]).append(": ");
StringBuilder value = new StringBuilder();
for (int i = 1; i < split.length; i++) value.append(split[i]);
if (!split[0].equals("Import-Package") && line.matches("^\\D+\\..+")) {
sb.append(remapper.map(value.toString()).replace('/', '.'));
} else {
sb.append(value);
}
}
}
sb.append("\n");
}
writeString(out, sb.toString());
} else if (entry.getName().startsWith("META-INF/services/")) {
StringBuilder sb = new StringBuilder();
for (String line : readLines(zipFile.getInputStream(entry))) {
if (line.startsWith("#")) {
sb.append(line);
} else if (line.matches("^\\D+\\..+")) { // if not blank:
sb.append(remapper.map(line).replace('/', '.'));
}
sb.append("\n");
}
writeString(out, sb.toString());
out.closeEntry();
String service = entry.getName().replaceFirst("META-INF/services/(.*)", "$1");
out.putNextEntry(new ZipEntry("META-INF/services/" + remapper.map(service).replace('/', '.')));
writeString(out, sb.toString());
} else {
ByteStreams.copy(zipFile.getInputStream(entry), out);
}
}
out.closeEntry();
}
zipFile.close();
out.close();
}

public static byte[] remapClassWithClassPrefix(@NotNull InputStream in, @NotNull String prefix, @NotNull Remapper remapper) throws IOException {
ClassReader cr = new ClassReader(in);
ClassWriter cw = new ClassWriter(0);
cr.accept(new ClassRemapper(cw, remapper), 0);
return cw.toByteArray();
}

public static void writeString(@NotNull OutputStream out, @NotNull String s) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(out);
writer.write(s);
writer.flush();
}

@NotNull
public static List<String> readLines(@NotNull InputStream in) throws IOException {
try (InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inputStreamReader)) {
List<String> list = new ArrayList<>();
String s;
while ((s = reader.readLine()) != null) list.add(s);
return list;
}
}
}
Loading

0 comments on commit c54a1d1

Please sign in to comment.