diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 46037f9ca..000000000
--- a/build.gradle
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Iris is a World Generator for Minecraft Bukkit Servers
- * Copyright (c) 2021 Arcane Arts (Volmit Software)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-buildscript() {
- repositories {
- maven { url 'https://jitpack.io'}
- }
- dependencies {
- classpath 'com.github.VolmitSoftware:NMSTools:1.0.1'
- }
-}
-
-plugins {
- id 'java'
- id 'java-library'
- id "io.github.goooler.shadow" version "8.1.7"
- id "de.undercouch.download" version "5.0.1"
-}
-
-
-version '3.6.5-1.20.1-1.21.4'
-
-// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
-// ======================== WINDOWS =============================
-registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins')
-registerCustomOutputTask('Psycho', 'C://Dan/MinecraftDevelopment/Server/plugins')
-registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins')
-registerCustomOutputTask('Coco', 'D://mcsm/plugins')
-registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
-registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
-registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
-registerCustomOutputTask('PixelFury', 'C://Users/repix/workplace/Iris/1.21.3 - Development-Public-v3/plugins')
-registerCustomOutputTask('PixelFuryDev', 'C://Users/repix/workplace/Iris/1.21 - Development-v3/plugins')
-// ========================== UNIX ==============================
-registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
-registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
-registerCustomOutputTaskUnix('PixelMac', '/Users/test/Desktop/mcserver/plugins')
-registerCustomOutputTaskUnix('CrazyDev22LT', '/home/julian/Desktop/server/plugins')
-// ==============================================================
-
-def NMS_BINDINGS = Map.of(
- "v1_21_R3", "1.21.4-R0.1-SNAPSHOT",
- "v1_21_R2", "1.21.3-R0.1-SNAPSHOT",
- "v1_21_R1", "1.21.1-R0.1-SNAPSHOT",
- "v1_20_R4", "1.20.6-R0.1-SNAPSHOT",
- "v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
- "v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
- "v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
-)
-def JVM_VERSION = Map.of()
-NMS_BINDINGS.each { nms ->
- project(":nms:${nms.key}") {
- apply plugin: 'java'
- apply plugin: 'com.volmit.nmstools'
-
- nmsTools {
- it.jvm = JVM_VERSION.getOrDefault(nms.key, 21)
- it.version = nms.value
- }
-
- dependencies {
- implementation project(":core")
- }
- }
-}
-
-shadowJar {
- NMS_BINDINGS.each {
- dependsOn(":nms:${it.key}:remap")
- from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}-mapped.jar")
- }
-
- //minimize()
- append("plugin.yml")
- relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
- relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
- relocate 'net.kyori', 'com.volmit.iris.util.kyori'
- relocate 'org.bstats', 'com.volmit.util.metrics'
- archiveFileName.set("Iris-${project.version}.jar")
-}
-
-dependencies {
- implementation project(':core')
-}
-
-configurations.configureEach {
- resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
- resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
-}
-
-allprojects {
- apply plugin: 'java'
-
- repositories {
- mavenCentral()
- maven { url "https://repo.papermc.io/repository/maven-public/" }
- maven { url "https://repo.codemc.org/repository/maven-public" }
- maven { url "https://mvn.lumine.io/repository/maven-public/" }
- maven { url "https://jitpack.io" }
-
- maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
- maven { url "https://mvn.lumine.io/repository/maven/" }
- maven { url "https://repo.triumphteam.dev/snapshots" }
- maven { url "https://repo.mineinabyss.com/releases" }
- maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
- maven { url "https://repo.nexomc.com/snapshots/" }
- maven { url "https://libraries.minecraft.net" }
- }
-
- dependencies {
- // Provided or Classpath
- compileOnly 'org.projectlombok:lombok:1.18.36'
- annotationProcessor 'org.projectlombok:lombok:1.18.36'
-
- // Shaded
- implementation 'com.dfsek:paralithic:0.8.1'
- implementation 'io.papermc:paperlib:1.0.5'
- implementation "net.kyori:adventure-text-minimessage:4.17.0"
- implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
- implementation 'net.kyori:adventure-api:4.17.0'
- implementation 'org.bstats:bstats-bukkit:3.1.0'
- //implementation 'org.bytedeco:javacpp:1.5.10'
- //implementation 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
- compileOnly 'io.lumine:Mythic-Dist:5.2.1'
- compileOnly 'io.lumine:MythicCrucible-Dist:2.0.0'
-
- // Dynamically Loaded
- compileOnly 'io.timeandspace:smoothie-map:2.0.2'
- compileOnly 'it.unimi.dsi:fastutil:8.5.8'
- compileOnly 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
- compileOnly 'org.zeroturnaround:zt-zip:1.14'
- compileOnly 'com.google.code.gson:gson:2.10.1'
- compileOnly 'org.ow2.asm:asm:9.2'
- compileOnly 'com.google.guava:guava:33.0.0-jre'
- compileOnly 'bsf:bsf:2.4.0'
- compileOnly 'rhino:js:1.7R2'
- compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
- compileOnly 'org.apache.commons:commons-lang3:3.12.0'
- compileOnly 'com.github.oshi:oshi-core:6.6.5'
- compileOnly 'org.apache.commons:commons-math3:3.6.1'
- }
-
- /**
- * We need parameter meta for the decree command system
- */
- compileJava {
- options.compilerArgs << '-parameters'
- options.encoding = "UTF-8"
- }
-
- javadoc {
- options.encoding = "UTF-8"
- options.addStringOption('Xdoclint:none', '-quiet')
- }
-
- task sourcesJar(type: Jar, dependsOn: classes) {
- archiveClassifier.set('sources')
- from sourceSets.main.allSource
- }
-
- task javadocJar(type: Jar, dependsOn: javadoc) {
- archiveClassifier.set('javadoc')
- from javadoc.destinationDir
- }
-}
-
-if (JavaVersion.current().toString() != "21") {
- System.err.println()
- System.err.println("=========================================================================================================")
- System.err.println("You must run gradle on Java 21. You are using " + JavaVersion.current())
- System.err.println()
- System.err.println("=== For IDEs ===")
- System.err.println("1. Configure the project for Java 21")
- System.err.println("2. Configure the bundled gradle to use Java 21 in settings")
- System.err.println()
- System.err.println("=== For Command Line (gradlew) ===")
- System.err.println("1. Install JDK 21 from https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html")
- System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-21.0.4")
- System.err.println("3. Open a new command prompt window to get the new environment variables if need be.")
- System.err.println("=========================================================================================================")
- System.err.println()
- System.exit(69);
-}
-
-task iris(type: Copy) {
- group "iris"
- from new File(layout.buildDirectory.asFile.get(), "libs/Iris-${version}.jar")
- into layout.buildDirectory.asFile.get()
- dependsOn(build)
-}
-
-// with classifier: 'javadoc' and 'sources'
-task irisDev(type: Copy) {
- group "iris"
- from("core/build/libs/core-javadoc.jar", "core/build/libs/core-sources.jar")
- rename { String fileName ->
- fileName.replace("core", "Iris-${version}")
- }
- into layout.buildDirectory.asFile.get()
- dependsOn(iris)
- dependsOn("core:sourcesJar")
- dependsOn("core:javadocJar")
-}
-
-
-def registerCustomOutputTask(name, path) {
- if (!System.properties['os.name'].toLowerCase().contains('windows')) {
- return;
- }
-
- tasks.register('build' + name, Copy) {
- group('development')
- outputs.upToDateWhen { false }
- dependsOn(iris)
- from(new File(buildDir, "Iris-" + version + ".jar"))
- into(file(path))
- rename { String fileName ->
- fileName.replace("Iris-" + version + ".jar", "Iris.jar")
- }
- }
-}
-
-def registerCustomOutputTaskUnix(name, path) {
- if (System.properties['os.name'].toLowerCase().contains('windows')) {
- return;
- }
-
- tasks.register('build' + name, Copy) {
- group('development')
- outputs.upToDateWhen { false }
- dependsOn(iris)
- from(new File(buildDir, "Iris-" + version + ".jar"))
- into(file(path))
- rename { String fileName ->
- fileName.replace("Iris-" + version + ".jar", "Iris.jar")
- }
- }
-}
-
-tasks.build.dependsOn(shadowJar)
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 000000000..462d697a2
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,280 @@
+import com.volmit.nmstools.NMSToolsExtension
+import com.volmit.nmstools.NMSToolsPlugin
+import de.undercouch.gradle.tasks.download.Download
+import xyz.jpenilla.runpaper.task.RunServer
+import kotlin.system.exitProcess
+
+/*
+ * Iris is a World Generator for Minecraft Bukkit Servers
+ * Copyright (c) 2021 Arcane Arts (Volmit Software)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+buildscript {
+ repositories.maven("https://jitpack.io")
+ dependencies.classpath("com.github.VolmitSoftware:NMSTools:c5cbc46ce6")
+}
+
+plugins {
+ java
+ `java-library`
+ alias(libs.plugins.shadow)
+ alias(libs.plugins.sentry)
+ alias(libs.plugins.download)
+ alias(libs.plugins.runPaper)
+}
+
+group = "com.volmit"
+version = "3.7.0-1.20.1-1.21.7"
+
+apply()
+
+// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
+// ======================== WINDOWS =============================
+registerCustomOutputTask("Cyberpwn", "C://Users/cyberpwn/Documents/development/server/plugins")
+registerCustomOutputTask("Psycho", "C://Dan/MinecraftDevelopment/Server/plugins")
+registerCustomOutputTask("ArcaneArts", "C://Users/arcane/Documents/development/server/plugins")
+registerCustomOutputTask("Coco", "D://mcsm/plugins")
+registerCustomOutputTask("Strange", "D://Servers/1.17 Test Server/plugins")
+registerCustomOutputTask("Vatuu", "D://Minecraft/Servers/1.19.4/plugins")
+registerCustomOutputTask("CrazyDev22", "C://Users/Julian/Desktop/server/plugins")
+registerCustomOutputTask("PixelFury", "C://Users/repix/workplace/Iris/1.21.3 - Development-Public-v3/plugins")
+registerCustomOutputTask("PixelFuryDev", "C://Users/repix/workplace/Iris/1.21 - Development-v3/plugins")
+// ========================== UNIX ==============================
+registerCustomOutputTaskUnix("CyberpwnLT", "/Users/danielmills/development/server/plugins")
+registerCustomOutputTaskUnix("PsychoLT", "/Users/brianfopiano/Developer/RemoteGit/Server/plugins")
+registerCustomOutputTaskUnix("PixelMac", "/Users/test/Desktop/mcserver/plugins")
+registerCustomOutputTaskUnix("CrazyDev22LT", "/home/julian/Desktop/server/plugins")
+// ==============================================================
+
+val serverMinHeap = "2G"
+val serverMaxHeap = "8G"
+//Valid values are: none, truecolor, indexed256, indexed16, indexed8
+val color = "truecolor"
+val errorReporting = false
+
+val nmsBindings = mapOf(
+ "v1_21_R5" to "1.21.7-R0.1-SNAPSHOT",
+ "v1_21_R4" to "1.21.5-R0.1-SNAPSHOT",
+ "v1_21_R3" to "1.21.4-R0.1-SNAPSHOT",
+ "v1_21_R2" to "1.21.3-R0.1-SNAPSHOT",
+ "v1_21_R1" to "1.21.1-R0.1-SNAPSHOT",
+ "v1_20_R4" to "1.20.6-R0.1-SNAPSHOT",
+ "v1_20_R3" to "1.20.4-R0.1-SNAPSHOT",
+ "v1_20_R2" to "1.20.2-R0.1-SNAPSHOT",
+ "v1_20_R1" to "1.20.1-R0.1-SNAPSHOT",
+)
+val jvmVersion = mapOf()
+nmsBindings.forEach { key, value ->
+ project(":nms:$key") {
+ apply()
+ apply()
+
+ repositories {
+ maven("https://libraries.minecraft.net")
+ }
+
+ extensions.configure(NMSToolsExtension::class) {
+ jvm = jvmVersion.getOrDefault(key, 21)
+ version = value
+ }
+
+ dependencies {
+ compileOnly(project(":core"))
+ compileOnly(rootProject.libs.annotations)
+ compileOnly(rootProject.libs.byteBuddy.core)
+ }
+ }
+
+ tasks.register("runServer-$key") {
+ group = "servers"
+ minecraftVersion(value.split("-")[0])
+ minHeapSize = serverMinHeap
+ maxHeapSize = serverMaxHeap
+ pluginJars(tasks.jar.flatMap { it.archiveFile })
+ javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(jvmVersion.getOrDefault(key, 21))}
+ runDirectory.convention(layout.buildDirectory.dir("run/$key"))
+ systemProperty("disable.watchdog", "")
+ systemProperty("net.kyori.ansi.colorLevel", color)
+ systemProperty("com.mojang.eula.agree", true)
+ systemProperty("iris.suppressReporting", !errorReporting)
+ jvmArgs("-javaagent:${project(":core:agent").tasks.jar.flatMap { it.archiveFile }.get().asFile.absolutePath}")
+ }
+}
+
+tasks {
+ jar {
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+ nmsBindings.forEach { key, _ ->
+ from(project(":nms:$key").tasks.named("remap").map { zipTree(it.outputs.files.singleFile) })
+ }
+ from(project(":core").tasks.shadowJar.flatMap { it.archiveFile }.map { zipTree(it) })
+ from(project(":core:agent").tasks.jar.flatMap { it.archiveFile })
+ archiveFileName.set("Iris-${project.version}.jar")
+ }
+
+ register("iris") {
+ group = "iris"
+ dependsOn("jar")
+ from(layout.buildDirectory.file("libs/Iris-${project.version}.jar"))
+ into(layout.buildDirectory)
+ }
+
+ register("irisDev") {
+ group = "iris"
+ from(project(":core").layout.buildDirectory.files("libs/core-javadoc.jar", "libs/core-sources.jar"))
+ rename { it.replace("core", "Iris-${project.version}") }
+ into(layout.buildDirectory)
+ dependsOn(":core:sourcesJar")
+ dependsOn(":core:javadocJar")
+ }
+
+ val cli = file("sentry-cli.exe")
+ register("downloadCli") {
+ group = "io.sentry"
+ src("https://release-registry.services.sentry.io/apps/sentry-cli/latest?response=download&arch=x86_64&platform=${System.getProperty("os.name")}&package=sentry-cli")
+ dest(cli)
+
+ doLast {
+ cli.setExecutable(true)
+ }
+ }
+
+ register("release") {
+ group = "io.sentry"
+ dependsOn("downloadCli")
+ doLast {
+ val authToken = project.findProperty("sentry.auth.token") ?: System.getenv("SENTRY_AUTH_TOKEN")
+ val org = "volmit-software"
+ val projectName = "iris"
+ exec(cli, "releases", "new", "--auth-token", authToken, "-o", org, "-p", projectName, version)
+ exec(cli, "releases", "set-commits", "--auth-token", authToken, "-o", org, "-p", projectName, version, "--auto", "--ignore-missing")
+ exec(cli, "releases", "finalize", "--auth-token", authToken, "-o", org, "-p", projectName, version)
+ cli.delete()
+ }
+ }
+}
+
+fun exec(vararg command: Any) {
+ val p = ProcessBuilder(command.map { it.toString() })
+ .start()
+ p.inputStream.reader().useLines { it.forEach(::println) }
+ p.errorStream.reader().useLines { it.forEach(::println) }
+ p.waitFor()
+}
+
+configurations.configureEach {
+ resolutionStrategy.cacheChangingModulesFor(60, "minutes")
+ resolutionStrategy.cacheDynamicVersionsFor(60, "minutes")
+}
+
+allprojects {
+ apply()
+
+ repositories {
+ mavenCentral()
+ maven("https://repo.papermc.io/repository/maven-public/")
+ maven("https://repo.codemc.org/repository/maven-public/")
+
+ maven("https://jitpack.io") // EcoItems, score
+ maven("https://repo.nexomc.com/releases/") // nexo
+ maven("https://maven.devs.beer/") // itemsadder
+ maven("https://repo.extendedclip.com/releases/") // placeholderapi
+ maven("https://mvn.lumine.io/repository/maven-public/") // mythic
+ maven("https://nexus.phoenixdevt.fr/repository/maven-public/") //MMOItems
+ maven("https://repo.onarandombox.com/content/groups/public/") //Multiverse Core
+ }
+
+ dependencies {
+ // Provided or Classpath
+ compileOnly(rootProject.libs.lombok)
+ annotationProcessor(rootProject.libs.lombok)
+ }
+
+ /**
+ * We need parameter meta for the decree command system
+ */
+ tasks {
+ compileJava {
+ options.compilerArgs.add("-parameters")
+ options.encoding = "UTF-8"
+ }
+
+ javadoc {
+ options.encoding = "UTF-8"
+ options.quiet()
+ //options.addStringOption("Xdoclint:none") // TODO: Re-enable this
+ }
+
+ register("sourcesJar") {
+ archiveClassifier.set("sources")
+ from(sourceSets.main.map { it.allSource })
+ }
+
+ register("javadocJar") {
+ archiveClassifier.set("javadoc")
+ from(javadoc.map { it.destinationDir!! })
+ }
+ }
+}
+
+if (JavaVersion.current().toString() != "21") {
+ System.err.println()
+ System.err.println("=========================================================================================================")
+ System.err.println("You must run gradle on Java 21. You are using " + JavaVersion.current())
+ System.err.println()
+ System.err.println("=== For IDEs ===")
+ System.err.println("1. Configure the project for Java 21")
+ System.err.println("2. Configure the bundled gradle to use Java 21 in settings")
+ System.err.println()
+ System.err.println("=== For Command Line (gradlew) ===")
+ System.err.println("1. Install JDK 21 from https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html")
+ System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-21.0.4")
+ System.err.println("3. Open a new command prompt window to get the new environment variables if need be.")
+ System.err.println("=========================================================================================================")
+ System.err.println()
+ exitProcess(69)
+}
+
+
+fun registerCustomOutputTask(name: String, path: String) {
+ if (!System.getProperty("os.name").lowercase().contains("windows")) {
+ return
+ }
+
+ tasks.register("build$name") {
+ group = "development"
+ outputs.upToDateWhen { false }
+ dependsOn("iris")
+ from(layout.buildDirectory.file("Iris-${project.version}.jar"))
+ into(file(path))
+ rename { "Iris.jar" }
+ }
+}
+
+fun registerCustomOutputTaskUnix(name: String, path: String) {
+ if (System.getProperty("os.name").lowercase().contains("windows")) {
+ return
+ }
+
+ tasks.register("build$name") {
+ group = "development"
+ outputs.upToDateWhen { false }
+ dependsOn("iris")
+ from(layout.buildDirectory.file("Iris-${project.version}.jar"))
+ into(file(path))
+ rename { "Iris.jar" }
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 000000000..c94238170
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,11 @@
+plugins {
+ kotlin("jvm") version "2.0.20"
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("org.ow2.asm:asm:9.8")
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ApiGenerator.kt b/buildSrc/src/main/kotlin/ApiGenerator.kt
new file mode 100644
index 000000000..530d4c6eb
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ApiGenerator.kt
@@ -0,0 +1,121 @@
+import org.gradle.api.DefaultTask
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.publish.PublishingExtension
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.jvm.tasks.Jar
+import org.objectweb.asm.*
+import java.io.File
+import java.util.jar.JarFile
+import java.util.jar.JarOutputStream
+
+class ApiGenerator : Plugin {
+ override fun apply(target: Project): Unit = with(target) {
+ plugins.apply("maven-publish")
+ val task = tasks.register("irisApi", GenerateApiTask::class.java)
+ extensions.findByType(PublishingExtension::class.java)!!.apply {
+ repositories.maven {
+ it.name = "deployDir"
+ it.url = targetDirectory.toURI()
+ }
+
+ publications.create("maven", MavenPublication::class.java) {
+ it.groupId = name
+ it.version = version.toString()
+ it.artifact(task)
+ }
+ }
+ }
+}
+
+abstract class GenerateApiTask : DefaultTask() {
+ init {
+ group = "iris"
+ dependsOn("jar")
+ finalizedBy("publishMavenPublicationToDeployDirRepository")
+ doLast {
+ logger.lifecycle("The API is located at ${outputFile.absolutePath}")
+ }
+ }
+
+ @InputFile
+ val inputFile: File = project.tasks
+ .named("jar", Jar::class.java)
+ .get()
+ .archiveFile
+ .get()
+ .asFile
+
+ @OutputFile
+ val outputFile: File = project.targetDirectory.resolve(inputFile.name)
+
+ @TaskAction
+ fun generate() {
+ JarFile(inputFile).use { jar ->
+ JarOutputStream(outputFile.apply { parentFile?.mkdirs() }.outputStream()).use { out ->
+ jar.stream()
+ .parallel()
+ .filter { !it.isDirectory }
+ .filter { it.name.endsWith(".class") }
+ .forEach {
+ val bytes = jar.getInputStream(it).use { input ->
+ val writer = ClassWriter(ClassWriter.COMPUTE_MAXS)
+ val visitor = MethodClearingVisitor(writer)
+ ClassReader(input).accept(visitor, 0)
+ writer.toByteArray()
+ }
+
+ synchronized(out) {
+ out.putNextEntry(it)
+ out.write(bytes)
+ out.closeEntry()
+ }
+ }
+ }
+ }
+ }
+}
+
+val Project.targetDirectory: File get() {
+ val dir = System.getenv("DEPLOY_DIR") ?: return project.layout.buildDirectory.dir("api").get().asFile
+ return File(dir)
+}
+
+private class MethodClearingVisitor(
+ cv: ClassVisitor
+) : ClassVisitor(Opcodes.ASM9, cv) {
+
+ override fun visitMethod(
+ access: Int,
+ name: String?,
+ descriptor: String?,
+ signature: String?,
+ exceptions: Array?
+ ) = ExceptionThrowingMethodVisitor(super.visitMethod(access, name, descriptor, signature, exceptions))
+}
+
+private class ExceptionThrowingMethodVisitor(
+ mv: MethodVisitor
+) : MethodVisitor(Opcodes.ASM9, mv) {
+
+ override fun visitCode() {
+ if (mv == null) return
+ mv.visitCode()
+
+ mv.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException")
+ mv.visitInsn(Opcodes.DUP)
+ mv.visitLdcInsn("Only API")
+ mv.visitMethodInsn(
+ Opcodes.INVOKESPECIAL,
+ "java/lang/IllegalStateException",
+ "", "(Ljava/lang/String;)V", false
+ )
+ mv.visitInsn(Opcodes.ATHROW)
+
+ mv.visitMaxs(0, 0)
+ mv.visitEnd()
+ }
+}
\ No newline at end of file
diff --git a/core/agent/build.gradle.kts b/core/agent/build.gradle.kts
new file mode 100644
index 000000000..a0d8024df
--- /dev/null
+++ b/core/agent/build.gradle.kts
@@ -0,0 +1,12 @@
+plugins {
+ java
+}
+
+tasks.jar {
+ manifest.attributes(
+ "Agent-Class" to "com.volmit.iris.util.agent.Installer",
+ "Premain-Class" to "com.volmit.iris.util.agent.Installer",
+ "Can-Redefine-Classes" to true,
+ "Can-Retransform-Classes" to true
+ )
+}
\ No newline at end of file
diff --git a/core/agent/src/main/java/com/volmit/iris/util/agent/Installer.java b/core/agent/src/main/java/com/volmit/iris/util/agent/Installer.java
new file mode 100644
index 000000000..3c68fd579
--- /dev/null
+++ b/core/agent/src/main/java/com/volmit/iris/util/agent/Installer.java
@@ -0,0 +1,29 @@
+package com.volmit.iris.util.agent;
+
+import java.lang.instrument.Instrumentation;
+
+public class Installer {
+ private static volatile Instrumentation instrumentation;
+
+ public static Instrumentation getInstrumentation() {
+ Instrumentation instrumentation = Installer.instrumentation;
+ if (instrumentation == null) {
+ throw new IllegalStateException("The agent is not loaded or this method is not called via the system class loader");
+ }
+ return instrumentation;
+ }
+
+ public static void premain(String arguments, Instrumentation instrumentation) {
+ doMain(instrumentation);
+ }
+
+ public static void agentmain(String arguments, Instrumentation instrumentation) {
+ doMain(instrumentation);
+ }
+
+ private static synchronized void doMain(Instrumentation instrumentation) {
+ if (Installer.instrumentation != null)
+ return;
+ Installer.instrumentation = instrumentation;
+ }
+}
\ No newline at end of file
diff --git a/core/build.gradle b/core/build.gradle
deleted file mode 100644
index 2c1e96fc2..000000000
--- a/core/build.gradle
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Iris is a World Generator for Minecraft Bukkit Servers
- * Copyright (c) 2021 Arcane Arts (Volmit Software)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-plugins {
- id 'java'
- id 'java-library'
- id "io.freefair.lombok" version "8.6"
-}
-
-def apiVersion = '1.19'
-def main = 'com.volmit.iris.Iris'
-
-/**
- * We need parameter meta for the decree command system
- */
-compileJava {
- options.compilerArgs << '-parameters'
- options.encoding = "UTF-8"
-}
-
-repositories {
- maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'}
- maven { url 'https://repo.auxilor.io/repository/maven-public/' }
-}
-
-/**
- * Dependencies.
- *
- * Provided or classpath dependencies are not shaded and are available on the runtime classpath
- *
- * Shaded dependencies are not available at runtime, nor are they available on mvn central so they
- * need to be shaded into the jar (increasing binary size)
- *
- * Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
- * plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
- * these dependencies if they are available on mvn central.
- */
-dependencies {
- // Provided or Classpath
- compileOnly 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT'
- compileOnly 'org.apache.logging.log4j:log4j-api:2.19.0'
- compileOnly 'org.apache.logging.log4j:log4j-core:2.19.0'
- compileOnly 'commons-io:commons-io:2.13.0'
- compileOnly 'commons-lang:commons-lang:2.6'
- compileOnly 'com.github.oshi:oshi-core:5.8.5'
- compileOnly 'org.lz4:lz4-java:1.8.0'
-
- // Third Party Integrations
- compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
- compileOnly 'com.nexomc:nexo:1.0.0-dev.38'
- compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
- compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
- compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
- compileOnly 'net.Indyuce:MMOItems-API:6.9.5-SNAPSHOT'
- compileOnly 'com.willfp:EcoItems:5.44.0'
- //implementation files('libs/CustomItems.jar')
-}
-
-java {
- disableAutoTargetJvm()
-}
-
-/**
- * Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
- */
-file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
-
-/**
- * Expand properties into plugin yml
- */
-processResources {
- filesMatching('**/plugin.yml') {
- expand(
- 'name': rootProject.name.toString(),
- 'version': rootProject.version.toString(),
- 'main': main.toString(),
- 'apiversion': apiVersion.toString()
- )
- }
-}
\ No newline at end of file
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
new file mode 100644
index 000000000..b40ab5d16
--- /dev/null
+++ b/core/build.gradle.kts
@@ -0,0 +1,159 @@
+import io.github.slimjar.func.slimjar
+import io.github.slimjar.resolver.data.Mirror
+import java.net.URI
+
+/*
+ * Iris is a World Generator for Minecraft Bukkit Servers
+ * Copyright (c) 2021 Arcane Arts (Volmit Software)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+plugins {
+ java
+ `java-library`
+ alias(libs.plugins.shadow)
+ alias(libs.plugins.sentry)
+ alias(libs.plugins.slimjar)
+}
+
+val apiVersion = "1.19"
+val main = "com.volmit.iris.Iris"
+val lib = "com.volmit.iris.util"
+
+/**
+ * Dependencies.
+ *
+ * Provided or classpath dependencies are not shaded and are available on the runtime classpath
+ *
+ * Shaded dependencies are not available at runtime, nor are they available on mvn central so they
+ * need to be shaded into the jar (increasing binary size)
+ *
+ * Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
+ * plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
+ * these dependencies if they are available on mvn central.
+ */
+dependencies {
+ // Provided or Classpath
+ compileOnly(libs.spigot)
+ compileOnly(libs.log4j.api)
+ compileOnly(libs.log4j.core)
+
+ // Third Party Integrations
+ compileOnly(libs.nexo)
+ compileOnly(libs.itemsadder)
+ compileOnly(libs.placeholderApi)
+ compileOnly(libs.score)
+ compileOnly(libs.mmoitems)
+ compileOnly(libs.ecoitems)
+ compileOnly(libs.mythic)
+ compileOnly(libs.mythicChrucible)
+ compileOnly(libs.kgenerators) {
+ isTransitive = false
+ }
+ compileOnly(libs.multiverseCore)
+
+ // Shaded
+ implementation(slimjar())
+
+ // Dynamically Loaded
+ slim(libs.paralithic)
+ slim(libs.paperlib)
+ slim(libs.adventure.api)
+ slim(libs.adventure.minimessage)
+ slim(libs.adventure.platform)
+ slim(libs.bstats)
+ slim(libs.sentry)
+
+ slim(libs.commons.io)
+ slim(libs.commons.lang)
+ slim(libs.commons.lang3)
+ slim(libs.commons.math3)
+ slim(libs.oshi)
+ slim(libs.lz4)
+ slim(libs.fastutil)
+ slim(libs.lru)
+ slim(libs.zip)
+ slim(libs.gson)
+ slim(libs.asm)
+ slim(libs.bsf)
+ slim(libs.rhino)
+ slim(libs.caffeine)
+ slim(libs.byteBuddy.core)
+ slim(libs.byteBuddy.agent)
+}
+
+java {
+ disableAutoTargetJvm()
+}
+
+sentry {
+ autoInstallation.enabled = false
+ includeSourceContext = true
+
+ org = "volmit-software"
+ projectName = "iris"
+ authToken = findProperty("sentry.auth.token") as String? ?: System.getenv("SENTRY_AUTH_TOKEN")
+}
+
+slimJar {
+ mirrors = listOf(Mirror(
+ URI.create("https://maven-central.storage-download.googleapis.com/maven2").toURL(),
+ URI.create("https://repo.maven.apache.org/maven2/").toURL()
+ ))
+
+ relocate("com.dfsek.paralithic", "$lib.paralithic")
+ relocate("io.papermc.lib", "$lib.paper")
+ relocate("net.kyori", "$lib.kyori")
+ relocate("org.bstats", "$lib.metrics")
+ relocate("io.sentry", "$lib.sentry")
+}
+
+tasks {
+ /**
+ * We need parameter meta for the decree command system
+ */
+ compileJava {
+ options.compilerArgs.add("-parameters")
+ options.encoding = "UTF-8"
+ }
+
+ /**
+ * Expand properties into plugin yml
+ */
+ processResources {
+ inputs.properties(
+ "name" to rootProject.name,
+ "version" to rootProject.version,
+ "apiVersion" to apiVersion,
+ "main" to main,
+ )
+ filesMatching("**/plugin.yml") {
+ expand(inputs.properties)
+ }
+ }
+
+ shadowJar {
+ mergeServiceFiles()
+ //minimize()
+ relocate("io.github.slimjar", "$lib.slimjar")
+ }
+}
+
+/**
+ * Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
+ */
+afterEvaluate {
+ layout.buildDirectory.file("resources/main/plugin.yml").get().asFile.delete()
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java
index 07e01c6e4..f299e4409 100644
--- a/core/src/main/java/com/volmit/iris/Iris.java
+++ b/core/src/main/java/com/volmit/iris/Iris.java
@@ -1,930 +1,877 @@
-/*
- * Iris is a World Generator for Minecraft Bukkit Servers
- * Copyright (c) 2022 Arcane Arts (Volmit Software)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.volmit.iris;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.volmit.iris.core.IrisSettings;
-import com.volmit.iris.core.ServerConfigurator;
-import com.volmit.iris.core.link.IrisPapiExpansion;
-import com.volmit.iris.core.link.MultiverseCoreLink;
-import com.volmit.iris.core.link.MythicMobsLink;
-import com.volmit.iris.core.loader.IrisData;
-import com.volmit.iris.core.nms.INMS;
-import com.volmit.iris.core.nms.v1X.NMSBinding1X;
-import com.volmit.iris.core.pregenerator.LazyPregenerator;
-import com.volmit.iris.core.service.StudioSVC;
-import com.volmit.iris.core.tools.IrisToolbelt;
-import com.volmit.iris.core.tools.IrisWorldCreator;
-import com.volmit.iris.engine.EnginePanic;
-import com.volmit.iris.engine.object.IrisCompat;
-import com.volmit.iris.engine.object.IrisContextInjector;
-import com.volmit.iris.engine.object.IrisDimension;
-import com.volmit.iris.engine.object.IrisWorld;
-import com.volmit.iris.engine.platform.BukkitChunkGenerator;
-import com.volmit.iris.engine.platform.DummyChunkGenerator;
-import com.volmit.iris.core.safeguard.IrisSafeguard;
-import com.volmit.iris.core.safeguard.UtilsSFG;
-import com.volmit.iris.engine.platform.PlatformChunkGenerator;
-import com.volmit.iris.util.collection.KList;
-import com.volmit.iris.util.collection.KMap;
-import com.volmit.iris.util.exceptions.IrisException;
-import com.volmit.iris.util.format.C;
-import com.volmit.iris.util.format.Form;
-import com.volmit.iris.util.function.NastyRunnable;
-import com.volmit.iris.util.io.FileWatcher;
-import com.volmit.iris.util.io.IO;
-import com.volmit.iris.util.io.InstanceState;
-import com.volmit.iris.util.io.JarScanner;
-import com.volmit.iris.util.math.M;
-import com.volmit.iris.util.math.RNG;
-import com.volmit.iris.util.misc.getHardware;
-import com.volmit.iris.util.parallel.MultiBurst;
-import com.volmit.iris.util.plugin.IrisService;
-import com.volmit.iris.util.plugin.VolmitPlugin;
-import com.volmit.iris.util.plugin.VolmitSender;
-import com.volmit.iris.util.reflect.ShadeFix;
-import com.volmit.iris.util.scheduling.J;
-import com.volmit.iris.util.scheduling.Queue;
-import com.volmit.iris.util.scheduling.ShurikenQueue;
-import io.papermc.lib.PaperLib;
-import net.kyori.adventure.platform.bukkit.BukkitAudiences;
-import net.kyori.adventure.text.serializer.ComponentSerializer;
-import org.bstats.bukkit.Metrics;
-import org.bstats.charts.DrilldownPie;
-import org.bstats.charts.SimplePie;
-import org.bstats.charts.SingleLineChart;
-import org.bukkit.*;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.entity.Player;
-import org.bukkit.event.*;
-import org.bukkit.generator.BiomeProvider;
-import org.bukkit.generator.ChunkGenerator;
-import org.bukkit.plugin.IllegalPluginAccessException;
-import org.bukkit.plugin.Plugin;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import oshi.SystemInfo;
-
-import java.io.*;
-import java.lang.annotation.Annotation;
-import java.math.RoundingMode;
-import java.net.URL;
-import java.text.NumberFormat;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
-import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware;
-
-@SuppressWarnings("CanBeFinal")
-public class Iris extends VolmitPlugin implements Listener {
- private static final Queue syncJobs = new ShurikenQueue<>();
-
- public static Iris instance;
- public static BukkitAudiences audiences;
- public static MultiverseCoreLink linkMultiverseCore;
- public static MythicMobsLink linkMythicMobs;
- public static IrisCompat compat;
- public static FileWatcher configWatcher;
- private static VolmitSender sender;
-
- static {
- try {
- fixShading();
- InstanceState.updateInstanceId();
- } catch (Throwable ignored) {
-
- }
- }
-
- private final KList postShutdown = new KList<>();
- private KMap, IrisService> services;
-
- public static VolmitSender getSender() {
- if (sender == null) {
- sender = new VolmitSender(Bukkit.getConsoleSender());
- sender.setTag(instance.getTag());
- }
- return sender;
- }
-
- @SuppressWarnings("unchecked")
- public static T service(Class c) {
- return (T) instance.services.get(c);
- }
-
- public static void callEvent(Event e) {
- if (!e.isAsynchronous()) {
- J.s(() -> Bukkit.getPluginManager().callEvent(e));
- } else {
- Bukkit.getPluginManager().callEvent(e);
- }
- }
-
- public static KList