diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 77af8afe2..000000000 --- a/build.gradle +++ /dev/null @@ -1,291 +0,0 @@ -import xyz.jpenilla.runpaper.task.RunServer - -/* - * 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" - id "xyz.jpenilla.run-paper" version "2.3.1" -} - - -version '3.6.9-1.20.1-1.21.5' - -// 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 MIN_HEAP_SIZE = "2G" -def MAX_HEAP_SIZE = "8G" -//Valid values are: none, truecolor, indexed256, indexed16, indexed8 -def COLOR = "truecolor" - -def NMS_BINDINGS = Map.of( - "v1_21_R4", "1.21.5-R0.1-SNAPSHOT", - "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.forEach { key, value -> - project(":nms:$key") { - apply plugin: 'java' - apply plugin: 'com.volmit.nmstools' - - nmsTools { - it.jvm = JVM_VERSION.getOrDefault(key, 21) - it.version = value - } - - dependencies { - implementation project(":core") - } - } - - tasks.register("runServer-$key", RunServer) { - group("servers") - minecraftVersion(value.split("-")[0]) - minHeapSize(MIN_HEAP_SIZE) - maxHeapSize(MAX_HEAP_SIZE) - pluginJars(tasks.shadowJar.archiveFile) - javaLauncher = javaToolchains.launcherFor { it.languageVersion = JavaLanguageVersion.of(JVM_VERSION.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) - jvmArgs("-javaagent:${tasks.shadowJar.archiveFile.get().asFile.absolutePath}") - } -} - -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 { - exclude(dependency("org.ow2.asm:asm:")) - exclude(dependency("org.jetbrains:")) - } - manifest.attributes( - 'Agent-Class': 'com.volmit.iris.util.agent.Installer', - 'Premain-Class': 'com.volmit.iris.util.agent.Installer', - 'Can-Redefine-Classes': true, - 'Can-Retransform-Classes': true - ) -} - -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/releases/" } - 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("net.bytebuddy:byte-buddy:1.17.5") - compileOnly("net.bytebuddy:byte-buddy-agent:1.17.5") - } - - /** - * 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..bb061f2bc --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,276 @@ +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` + id("com.gradleup.shadow") version "8.3.6" + id("de.undercouch.download") version "5.0.1" + id("xyz.jpenilla.run-paper") version "2.3.1" + id("io.sentry.jvm.gradle") version "5.7.0" +} + +version = "3.6.10-1.20.1-1.21.5" + +// 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 nmsBindings = mapOf( + "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("org.jetbrains:annotations:26.0.2") + } + } + + 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) + } +} + +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) }) + 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() +} + +dependencies { + implementation(project(":core")) +} + +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://mvn.lumine.io/repository/maven-public/") + maven("https://jitpack.io") + + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + maven("https://mvn.lumine.io/repository/maven/") + maven("https://repo.triumphteam.dev/snapshots") + maven("https://repo.mineinabyss.com/releases") + maven("https://hub.jeff-media.com/nexus/repository/jeff-media-public/") + maven("https://repo.nexomc.com/releases/") + } + + dependencies { + // Provided or Classpath + compileOnly("org.projectlombok:lombok:1.18.36") + annotationProcessor("org.projectlombok:lombok:1.18.36") + } + + /** + * 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/core/build.gradle b/core/build.gradle deleted file mode 100644 index 9effb5654..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.6.0' - 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..cebfbc6c5 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,151 @@ +/* + * 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` + id("com.gradleup.shadow") + id("io.sentry.jvm.gradle") +} + +val apiVersion = "1.19" +val main = "com.volmit.iris.Iris" + +repositories { + maven("https://nexus.phoenixdevt.fr/repository/maven-public/") + maven("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.nexomc:nexo:1.6.0") + 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") + + + // 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") +} + +java { + disableAutoTargetJvm() +} + +sentry { + includeSourceContext = true + + org = "volmit-software" + projectName = "iris" + authToken = findProperty("sentry.auth.token") as String? ?: System.getenv("SENTRY_AUTH_TOKEN") +} + +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() + 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.iris.util.metrics") + relocate("io.sentry", "com.volmit.iris.util.sentry") + + //minimize() + dependencies { + exclude(dependency("org.ow2.asm:asm:")) + exclude(dependency("org.jetbrains:")) + } + } +} + +/** + * 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 22fa07cc7..cc04f96c8 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -43,6 +43,7 @@ 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.context.IrisContext; import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; @@ -62,7 +63,10 @@ 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 com.volmit.iris.util.sentry.Attachments; +import com.volmit.iris.util.sentry.IrisLogger; import io.papermc.lib.PaperLib; +import io.sentry.Sentry; import lombok.NonNull; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.serializer.ComponentSerializer; @@ -391,6 +395,7 @@ public class Iris extends VolmitPlugin implements Listener { } public static void reportError(Throwable e) { + Sentry.captureException(e); if (IrisSettings.get().getGeneral().isDebug()) { String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber(); @@ -455,6 +460,7 @@ public class Iris extends VolmitPlugin implements Listener { instance = this; services = new KMap<>(); setupAudience(); + setupSentry(); initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class) i.getClass(), (IrisService) i)); IO.delete(new File("iris")); compat = IrisCompat.configured(getDataFile("compat.json")); @@ -524,6 +530,7 @@ public class Iris extends VolmitPlugin implements Listener { } } catch (Throwable e) { e.printStackTrace(); + reportError(e); } } @@ -541,7 +548,7 @@ public class Iris extends VolmitPlugin implements Listener { }); }); } catch (IrisException e) { - e.printStackTrace(); + reportError(e); } } } @@ -941,4 +948,35 @@ public class Iris extends VolmitPlugin implements Listener { return -1; } } + + private static void setupSentry() { + var settings = IrisSettings.get().getSentry(); + if (settings.disableAutoReporting || Sentry.isEnabled()) return; + Iris.info("Enabling Sentry for anonymous error reporting. You can disable this in the settings."); + Sentry.init(options -> { + options.setDsn("https://b16ecc222e9c1e0c48faecacb906fd89@o4509451052646400.ingest.de.sentry.io/4509452722765904"); + if (settings.debug) { + options.setLogger(new IrisLogger()); + options.setDebug(true); + } + + options.setAttachServerName(false); + options.setEnableUncaughtExceptionHandler(false); + options.setRelease(Iris.instance.getDescription().getVersion()); + options.setBeforeSend((event, hint) -> { + event.setTag("iris.safeguard", IrisSafeguard.mode()); + event.setTag("iris.nms", INMS.get().getClass().getCanonicalName()); + var context = IrisContext.get(); + if (context != null) event.getContexts().set("engine", context.asContext()); + return event; + }); + }); + Sentry.configureScope(scope -> { + scope.addAttachment(Attachments.PLUGINS); + scope.setTag("server", Bukkit.getVersion()); + scope.setTag("server.type", Bukkit.getName()); + scope.setTag("server.api", Bukkit.getBukkitVersion()); + }); + Runtime.getRuntime().addShutdownHook(new Thread(Sentry::close)); + } } diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index b7e5bae20..7804b3eac 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -46,6 +46,7 @@ public class IrisSettings { private IrisSettingsPerformance performance = new IrisSettingsPerformance(); private IrisSettingsUpdater updater = new IrisSettingsUpdater(); private IrisSettingsPregen pregen = new IrisSettingsPregen(); + private IrisSettingsSentry sentry = new IrisSettingsSentry(); public static int getThreadCount(int c) { return switch (c) { @@ -131,7 +132,7 @@ public class IrisSettings { public boolean markerEntitySpawningSystem = true; public boolean effectSystem = true; public boolean worldEditWandCUI = true; - public boolean globalPregenCache = true; + public boolean globalPregenCache = false; } @Data @@ -222,6 +223,12 @@ public class IrisSettings { } } + @Data + public static class IrisSettingsSentry { + public boolean disableAutoReporting = false; + public boolean debug = false; + } + @Data public static class IrisSettingsGUI { public boolean useServerLaunchedGuis = true; diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 5d6090b00..e96eb29ed 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -26,6 +26,7 @@ import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.annotations.Decree; @@ -71,6 +72,13 @@ public class CommandDeveloper implements DecreeExecutor { .engineStatus(sender()); } + @Decree(description = "Send a test exception to sentry") + public void Sentry() { + Engine engine = engine(); + if (engine != null) IrisContext.getOr(engine); + Iris.reportError(new Exception("This is a test")); + } + @Decree(description = "Test") public void dumpThreads() { try { diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java index 899ff7270..ccbf91c11 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java @@ -241,7 +241,8 @@ public class CommandObject implements DecreeExecutor { Location[] b = WandSVC.getCuboid(player()); - if (b == null) { + if (b == null || b[0] == null || b[1] == null) { + sender().sendMessage("No area selected."); return; } Location a1 = b[0].clone(); @@ -417,6 +418,10 @@ public class CommandObject implements DecreeExecutor { } Location[] b = WandSVC.getCuboid(player()); + if (b == null || b[0] == null || b[1] == null) { + sender().sendMessage("No area selected."); + return; + } Location a1 = b[0].clone(); Location a2 = b[1].clone(); Direction d = Direction.closest(player().getLocation().getDirection()).reverse(); @@ -477,6 +482,10 @@ public class CommandObject implements DecreeExecutor { } Location[] b = WandSVC.getCuboid(player()); + if (b == null || b[0] == null || b[1] == null) { + sender().sendMessage("No area selected."); + return; + } Location a1 = b[0].clone(); Location a2 = b[1].clone(); Location a1x = b[0].clone(); @@ -524,6 +533,10 @@ public class CommandObject implements DecreeExecutor { } Location[] b = WandSVC.getCuboid(player()); + if (b == null || b[0] == null || b[1] == null) { + sender().sendMessage("No area selected."); + return; + } b[0].add(new Vector(0, 1, 0)); b[1].add(new Vector(0, 1, 0)); Location a1 = b[0].clone(); diff --git a/core/src/main/java/com/volmit/iris/core/link/WorldEditLink.java b/core/src/main/java/com/volmit/iris/core/link/WorldEditLink.java index 42e335a10..638c66cc2 100644 --- a/core/src/main/java/com/volmit/iris/core/link/WorldEditLink.java +++ b/core/src/main/java/com/volmit/iris/core/link/WorldEditLink.java @@ -47,6 +47,7 @@ public class WorldEditLink { } catch (Throwable e) { Iris.error("Could not get selection"); e.printStackTrace(); + Iris.reportError(e); active.reset(); active.aquire(() -> false); } diff --git a/core/src/main/java/com/volmit/iris/core/loader/IrisData.java b/core/src/main/java/com/volmit/iris/core/loader/IrisData.java index e51c93176..a272be0d7 100644 --- a/core/src/main/java/com/volmit/iris/core/loader/IrisData.java +++ b/core/src/main/java/com/volmit/iris/core/loader/IrisData.java @@ -300,6 +300,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory { return r; } catch (Throwable e) { + Iris.reportError(e); e.printStackTrace(); Iris.error("Failed to create loader! " + registrant.getCanonicalName()); } diff --git a/core/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java b/core/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java index 6575abd37..a9b468e57 100644 --- a/core/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java +++ b/core/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java @@ -45,6 +45,7 @@ import lombok.ToString; import java.io.*; import java.util.Locale; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -240,8 +241,10 @@ public class ResourceLoader implements MeteredCache { for (String i : s) { burst.queue(() -> { T t = load(i); + if (t == null) + return; - if (t != null) { + synchronized (m) { m.add(t); } }); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index 9f9bde99e..572ce98d4 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -109,6 +109,7 @@ public class ChunkUpdater { } } } catch (Exception e) { + Iris.reportError(e); e.printStackTrace(); } }, 0, 3, TimeUnit.SECONDS); @@ -314,6 +315,7 @@ public class ChunkUpdater { world.save(); }).get(); } catch (Throwable e) { + Iris.reportError(e); e.printStackTrace(); } } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java b/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java index bf48e06e9..b9a3de943 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java @@ -7,6 +7,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.RegionCoordinates; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.parallel.HyperLock; import lombok.RequiredArgsConstructor; import net.jpountz.lz4.LZ4BlockInputStream; @@ -70,6 +71,7 @@ class PregenCacheImpl implements PregenCache { return new Plate(key, in); } catch (IOException e){ Iris.error("Failed to read pregen cache " + file); + Iris.reportError(e); e.printStackTrace(); return new Plate(key); } @@ -82,10 +84,11 @@ class PregenCacheImpl implements PregenCache { hyperLock.lock(plate.pos.x, plate.pos.z); try { File file = fileForPlate(plate.pos); - try (var out = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(file)))) { - plate.write(out); + try { + IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), plate::write); } catch (IOException e) { Iris.error("Failed to write pregen cache " + file); + Iris.reportError(e); e.printStackTrace(); } } finally { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 757dfcf8f..0dcfffcfc 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -157,7 +157,10 @@ public class AsyncPregenMethod implements PregeneratorMethod { } catch (Throwable e) { Iris.warn("Failed to increase worker threads, if you are on paper or a fork of it please increase it manually to " + adjusted); Iris.warn("For more information see https://docs.papermc.io/paper/reference/global-configuration#chunk_system_worker_threads"); - if (e instanceof InvocationTargetException) e.printStackTrace(); + if (e instanceof InvocationTargetException) { + Iris.reportError(e); + e.printStackTrace(); + } } return 0; }); @@ -173,6 +176,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { method.invoke(pool, i); return 0; } catch (Throwable e) { + Iris.reportError(e); Iris.error("Failed to reset worker threads"); e.printStackTrace(); } @@ -201,6 +205,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { }).get(); } catch (InterruptedException ignored) { } catch (Throwable e) { + Iris.reportError(e); e.printStackTrace(); } finally { semaphore.release(); @@ -219,6 +224,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { public void generate(int x, int z, PregenListener listener) { PaperLib.getChunkAtAsync(world, x, z, true, urgent) .exceptionally(e -> { + Iris.reportError(e); e.printStackTrace(); return null; }) diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java b/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java index 5217be9f2..2c9eb9be1 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java @@ -20,5 +20,15 @@ public class IrisSafeguard { Iris.instance.splash(); UtilsSFG.splash(); } + + public static String mode() { + if (unstablemode) { + return "unstable"; + } else if (warningmode) { + return "warning"; + } else { + return "stable"; + } + } } diff --git a/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java b/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java index 32d6af184..e8c194974 100644 --- a/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java @@ -23,9 +23,11 @@ public class GlobalCacheSVC implements IrisService { private static final Cache REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build(); private final KMap globalCache = new KMap<>(); private transient boolean lastState; + private static boolean disabled = true; @Override public void onEnable() { + disabled = false; lastState = !IrisSettings.get().getWorld().isGlobalPregenCache(); if (lastState) return; Bukkit.getWorlds().forEach(this::createCache); @@ -33,7 +35,8 @@ public class GlobalCacheSVC implements IrisService { @Override public void onDisable() { - globalCache.values().forEach(PregenCache::write); + disabled = true; + globalCache.qclear((world, cache) -> cache.write()); } @Nullable @@ -99,6 +102,7 @@ public class GlobalCacheSVC implements IrisService { } private static PregenCache createDefault0(String worldName) { + if (disabled) return PregenCache.EMPTY; return PregenCache.create(new File(Bukkit.getWorldContainer(), String.join(File.separator, worldName, "iris", "pregen"))).sync(); } } diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index 51351f657..df3951ea1 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -187,7 +187,7 @@ public class IrisEngineSVC implements IrisService { return; try { - engine.getMantle().trim(tectonicLimit.get() / worlds.size()); + engine.getMantle().trim(tectonicLimit()); } catch (Throwable e) { Iris.reportError(e); Iris.error("EngineSVC: Failed to trim for " + name); @@ -204,7 +204,7 @@ public class IrisEngineSVC implements IrisService { try { long unloadStart = System.currentTimeMillis(); - int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / worlds.size()); + int count = engine.getMantle().unloadTectonicPlate(tectonicLimit()); if (count > 0) { Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2)); } @@ -217,6 +217,10 @@ public class IrisEngineSVC implements IrisService { } } + private int tectonicLimit() { + return tectonicLimit.get() / Math.max(worlds.size(), 1); + } + @Synchronized private void close() { if (closed) return; diff --git a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java index 53d3800ac..8d984ba91 100644 --- a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java @@ -51,6 +51,7 @@ import org.bukkit.util.Vector; import java.awt.Color; import java.util.ArrayList; +import java.util.Arrays; import java.util.Objects; import java.util.concurrent.CountDownLatch; @@ -80,6 +81,8 @@ public class WandSVC implements IrisService { try { Location[] f = getCuboid(p); + if (f == null || f[0] == null || f[1] == null) + return null; Cuboid c = new Cuboid(f[0], f[1]); IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ()); @@ -198,7 +201,9 @@ public class WandSVC implements IrisService { public static Location stringToLocation(String s) { try { String[] f = s.split("\\Q in \\E"); + if (f.length != 2) return null; String[] g = f[0].split("\\Q,\\E"); + if (g.length != 3) return null; return new Location(Bukkit.getWorld(f[1]), Integer.parseInt(g[0]), Integer.parseInt(g[1]), Integer.parseInt(g[2])); } catch (Throwable e) { Iris.reportError(e); @@ -357,6 +362,7 @@ public class WandSVC implements IrisService { try { if ((IrisSettings.get().getWorld().worldEditWandCUI && isHoldingWand(p)) || isWand(p.getInventory().getItemInMainHand())) { Location[] d = getCuboid(p); + if (d == null || d[0] == null || d[1] == null) return; new WandSelection(new Cuboid(d[0], d[1]), p).draw(); } } catch (Throwable e) { diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index 9a87d26e9..47aa816d3 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -78,7 +78,6 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; import java.awt.Color; -import java.util.Arrays; import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -457,14 +456,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } } - for (int i = 0; i < 4; i++) { - try { - Arrays.parallelSort(nitems, (a, b) -> rng.nextInt()); - break; - } catch (Throwable e) { - Iris.reportError(e); - - } + for (int i = nitems.length; i > 1; i--) { + int j = rng.nextInt(i); + ItemStack tmp = nitems[i - 1]; + nitems[i - 1] = nitems[j]; + nitems[j] = tmp; } inventory.setContents(nitems); diff --git a/core/src/main/java/com/volmit/iris/engine/framework/EnginePlayer.java b/core/src/main/java/com/volmit/iris/engine/framework/EnginePlayer.java index 803819831..2350b3140 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/EnginePlayer.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/EnginePlayer.java @@ -47,9 +47,7 @@ public class EnginePlayer { } public void tick() { - sample(); - - if (!IrisSettings.get().getWorld().isEffectSystem()) + if (sample() || !IrisSettings.get().getWorld().isEffectSystem()) return; J.a(() -> { @@ -81,22 +79,22 @@ public class EnginePlayer { return M.ms() - lastSample; } - public void sample() { + public boolean sample() { + Location current = player.getLocation().clone(); + if (current.getWorld() != engine.getWorld().realWorld()) + return true; try { - if (ticksSinceLastSample() > 55 && player.getLocation().distanceSquared(lastLocation) > 9 * 9) { - lastLocation = player.getLocation().clone(); + if (ticksSinceLastSample() > 55 && current.distanceSquared(lastLocation) > 9 * 9) { + lastLocation = current; lastSample = M.ms(); - sampleBiomeRegion(); + biome = engine.getBiome(current); + region = engine.getRegion(current); } + return false; } catch (Throwable e) { Iris.reportError(e); } - } - - private void sampleBiomeRegion() { - Location l = player.getLocation(); - biome = engine.getBiome(l); - region = engine.getRegion(l); + return true; } } diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java index 31762626f..8d067abfd 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java @@ -58,21 +58,21 @@ public class MantleCarvingComponent extends IrisMantleComponent { @ChunkCoordinates private void carve(IrisCarving carving, MantleWriter writer, RNG rng, int cx, int cz) { - carving.doCarving(writer, rng, getEngineMantle().getEngine(), cx << 4, -1, cz << 4); + carving.doCarving(writer, rng, getEngineMantle().getEngine(), cx << 4, -1, cz << 4, 0); } private int computeRadius() { var dimension = getDimension(); int max = 0; - max = Math.max(max, dimension.getCarving().getMaxRange(getData())); + max = Math.max(max, dimension.getCarving().getMaxRange(getData(), 0)); for (var i : dimension.getAllRegions(this::getData)) { - max = Math.max(max, i.getCarving().getMaxRange(getData())); + max = Math.max(max, i.getCarving().getMaxRange(getData(), 0)); } for (var i : dimension.getAllBiomes(this::getData)) { - max = Math.max(max, i.getCarving().getMaxRange(getData())); + max = Math.max(max, i.getCarving().getMaxRange(getData(), 0)); } return max; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCarving.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCarving.java index bf7efa6af..1da8b1a31 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCarving.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCarving.java @@ -61,21 +61,25 @@ public class IrisCarving { @BlockCoordinates - public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { - doCarving(writer, rng, engine, x, y, z, -1); + public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int depth) { + doCarving(writer, rng, engine, x, y, z, depth, -1); } @BlockCoordinates - public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int waterHint) { + public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int recursion, int waterHint) { + int nextRecursion = recursion + 1; + if (caves.isNotEmpty()) { for (IrisCavePlacer i : caves) { - i.generateCave(writer, rng, engine, x, y, z, waterHint); + if (recursion > i.getMaxRecursion()) continue; + i.generateCave(writer, rng, engine, x, y, z, nextRecursion, waterHint); } } if (ravines.isNotEmpty()) { for (IrisRavinePlacer i : ravines) { - i.generateRavine(writer, rng, engine, x, y, z, waterHint); + if (recursion > i.getMaxRecursion()) continue; + i.generateRavine(writer, rng, engine, x, y, z, nextRecursion, waterHint); } } @@ -104,15 +108,18 @@ public class IrisCarving { } } - public int getMaxRange(IrisData data) { + public int getMaxRange(IrisData data, int recursion) { int max = 0; + int nextRecursion = recursion + 1; for (IrisCavePlacer i : caves) { - max = Math.max(max, i.getSize(data)); + if (recursion > i.getMaxRecursion()) continue; + max = Math.max(max, i.getSize(data, nextRecursion)); } for (IrisRavinePlacer i : ravines) { - max = Math.max(max, i.getSize(data)); + if (recursion > i.getMaxRecursion()) continue; + max = Math.max(max, i.getSize(data, nextRecursion)); } if (elipsoids.isNotEmpty()) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCave.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCave.java index 32ab22439..e0e818403 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCave.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCave.java @@ -66,10 +66,10 @@ public class IrisCave extends IrisRegistrant { } public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { - generate(writer, rng, engine, x, y, z, -1); + generate(writer, rng, engine, x, y, z, 0, -1); } - public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int waterHint) { + public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int recursion, int waterHint) { double girth = getWorm().getGirth().get(rng, x, z, engine.getData()); KList points = getWorm().generate(rng, engine.getData(), writer, verticalRange, x, y, z, (at) -> { @@ -92,7 +92,7 @@ public class IrisCave extends IrisRegistrant { int h = Math.min(Math.max(highestWater, waterHint), engine.getDimension().getFluidHeight()); for (IrisPosition i : points) { - fork.doCarving(writer, rng, engine, i.getX(), i.getY(), i.getZ(), h); + fork.doCarving(writer, rng, engine, i.getX(), i.getY(), i.getZ(), recursion, h); } MatterCavern c = new MatterCavern(true, customBiome, (byte) 0); @@ -108,7 +108,7 @@ public class IrisCave extends IrisRegistrant { } - public int getMaxSize(IrisData data) { - return getWorm().getMaxDistance() + fork.getMaxRange(data); + public int getMaxSize(IrisData data, int depth) { + return getWorm().getMaxDistance() + fork.getMaxRange(data, depth); } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java index acaa55904..1a95493a1 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java @@ -50,6 +50,10 @@ public class IrisCavePlacer implements IRare { @Desc("The cave to place") @RegistryListResource(IrisCave.class) private String cave; + @MinNumber(1) + @MaxNumber(256) + @Desc("The maximum recursion depth") + private int maxRecursion = 16; @Desc("If set to true, this cave is allowed to break the surface") private boolean breakSurface = true; @Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.") @@ -60,10 +64,10 @@ public class IrisCavePlacer implements IRare { } public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) { - generateCave(mantle, rng, engine, x, y, z, -1); + generateCave(mantle, rng, engine, x, y, z, 0, -1); } - public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z, int waterHint) { + public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z, int recursion, int waterHint) { if (fail.get()) { return; } @@ -92,18 +96,18 @@ public class IrisCavePlacer implements IRare { } try { - cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), waterHint); + cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), recursion, waterHint); } catch (Throwable e) { e.printStackTrace(); fail.set(true); } } - public int getSize(IrisData data) { + public int getSize(IrisData data, int depth) { IrisCave cave = getRealCave(data); if (cave != null) { - return cave.getMaxSize(data); + return cave.getMaxSize(data, depth); } return 32; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisRavine.java b/core/src/main/java/com/volmit/iris/engine/object/IrisRavine.java index ca6bb7bd4..e2d9a79e4 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisRavine.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisRavine.java @@ -93,10 +93,10 @@ public class IrisRavine extends IrisRegistrant { } public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { - generate(writer, rng, engine, x, y, z, -1); + generate(writer, rng, engine, x, y, z, 0, -1); } - public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int waterHint) { + public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int recursion, int waterHint) { KList pos = getWorm().generate(rng, engine.getData(), writer, null, x, y, z, (at) -> { }); CNG dg = depthStyle.getGenerator().createNoCache(rng, engine.getData()); @@ -135,7 +135,7 @@ public class IrisRavine extends IrisRegistrant { int width = (int) Math.round(bw.fitDouble(baseWidthStyle.getMin(), baseWidthStyle.getMax(), p.getX(), p.getZ())); int surface = (int) Math.round(rsurface - depth * 0.45); - fork.doCarving(writer, rng, engine, p.getX(), rng.i(surface - depth, surface), p.getZ(), Math.max(highestWater, waterHint)); + fork.doCarving(writer, rng, engine, p.getX(), rng.i(surface - depth, surface), p.getZ(), recursion, Math.max(highestWater, waterHint)); for (int i = surface + depth; i >= surface; i--) { if (i % ribThickness == 0) { @@ -184,7 +184,7 @@ public class IrisRavine extends IrisRegistrant { } - public int getMaxSize(IrisData data) { - return getWorm().getMaxDistance() + fork.getMaxRange(data); + public int getMaxSize(IrisData data, int depth) { + return getWorm().getMaxDistance() + fork.getMaxRange(data, depth); } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisRavinePlacer.java b/core/src/main/java/com/volmit/iris/engine/object/IrisRavinePlacer.java index 570859a63..fa65c5c79 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisRavinePlacer.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisRavinePlacer.java @@ -50,16 +50,20 @@ public class IrisRavinePlacer implements IRare { @Desc("The ravine to place") @RegistryListResource(IrisRavine.class) private String ravine; + @MinNumber(1) + @MaxNumber(256) + @Desc("The maximum recursion depth") + private int maxRecursion = 100; public IrisRavine getRealRavine(IrisData data) { return ravineCache.aquire(() -> data.getRavineLoader().load(getRavine())); } public void generateRavine(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) { - generateRavine(mantle, rng, engine, x, y, z, -1); + generateRavine(mantle, rng, engine, x, y, z, 0, -1); } - public void generateRavine(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z, int waterHint) { + public void generateRavine(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z, int recursion, int waterHint) { if (fail.get()) { return; } @@ -80,14 +84,14 @@ public class IrisRavinePlacer implements IRare { try { int xx = x + rng.nextInt(15); int zz = z + rng.nextInt(15); - ravine.generate(mantle, rng, engine, xx, y, zz, waterHint); + ravine.generate(mantle, rng, engine, xx, y, zz, recursion, waterHint); } catch (Throwable e) { e.printStackTrace(); fail.set(true); } } - public int getSize(IrisData data) { - return getRealRavine(data).getMaxSize(data); + public int getSize(IrisData data, int depth) { + return getRealRavine(data).getMaxSize(data, depth); } } diff --git a/core/src/main/java/com/volmit/iris/util/collection/KMap.java b/core/src/main/java/com/volmit/iris/util/collection/KMap.java index 01baab32b..4a7f938e0 100644 --- a/core/src/main/java/com/volmit/iris/util/collection/KMap.java +++ b/core/src/main/java/com/volmit/iris/util/collection/KMap.java @@ -23,11 +23,9 @@ import com.volmit.iris.util.function.Consumer2; import com.volmit.iris.util.function.Consumer3; import com.volmit.iris.util.scheduling.Queue; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; import java.util.function.BiFunction; @SuppressWarnings("ALL") @@ -373,6 +371,20 @@ public class KMap extends ConcurrentHashMap { return g; } + public KMap qclear(BiConsumer action) { + final Iterator> it = entrySet().iterator(); + while (it.hasNext()) { + final Map.Entry entry = it.next(); + it.remove(); + try { + action.accept(entry.getKey(), entry.getValue()); + } catch (Throwable e) { + Iris.reportError(e); + } + } + return this; + } + /** * Create a keypair queue * diff --git a/core/src/main/java/com/volmit/iris/util/context/IrisContext.java b/core/src/main/java/com/volmit/iris/util/context/IrisContext.java index 8b69eb867..b076b5eef 100644 --- a/core/src/main/java/com/volmit/iris/util/context/IrisContext.java +++ b/core/src/main/java/com/volmit/iris/util/context/IrisContext.java @@ -87,4 +87,21 @@ public class IrisContext { public IrisComplex getComplex() { return engine.getComplex(); } + + public KMap asContext() { + var hash32 = engine.getHash32().getNow(null); + var dimension = engine.getDimension(); + var mantle = engine.getMantle(); + return new KMap() + .qput("studio", engine.isStudio()) + .qput("closed", engine.isClosed()) + .qput("pack", new KMap<>() + .qput("key", dimension.getLoadKey()) + .qput("version", dimension.getVersion()) + .qput("hash", hash32 == null ? "" : Long.toHexString(hash32))) + .qput("mantle", new KMap<>() + .qput("idle", mantle.getAdjustedIdleDuration()) + .qput("loaded", mantle.getLoadedRegionCount()) + .qput("queued", mantle.getUnloadRegionCount())); + } } diff --git a/core/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java b/core/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java index e76f62965..d22a8b822 100644 --- a/core/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java +++ b/core/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java @@ -160,7 +160,8 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { } J.aBukkit(() -> { - if (!call(new VolmitSender(sender), args)) { + var volmit = new VolmitSender(sender); + if (!call(volmit, args)) { if (IrisSettings.get().getGeneral().isCommandSounds()) { if (sender instanceof Player) { @@ -169,7 +170,7 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { } } - sender.sendMessage(C.RED + "Unknown Iris Command"); + volmit.sendMessage(C.RED + "Unknown Iris Command"); } else { if (IrisSettings.get().getGeneral().isCommandSounds()) { if (sender instanceof Player) { diff --git a/core/src/main/java/com/volmit/iris/util/format/C.java b/core/src/main/java/com/volmit/iris/util/format/C.java index de1893c8f..85deb3cac 100644 --- a/core/src/main/java/com/volmit/iris/util/format/C.java +++ b/core/src/main/java/com/volmit/iris/util/format/C.java @@ -376,6 +376,28 @@ public enum C { return "#" + Integer.toHexString(spin(color.awtColor(), h, s, b).getRGB()).substring(2); } + public static String mini(String s) { + String msg = compress(s); + StringBuilder b = new StringBuilder(); + boolean c = false; + + for (char i : msg.toCharArray()) { + if (!c) { + if (i == C.COLOR_CHAR) { + c = true; + continue; + } + b.append(i); + } else { + c = false; + C o = C.getByChar(i); + b.append(o.token); + } + } + + return b.toString(); + } + public static String aura(String s, int hrad, int srad, int vrad) { return aura(s, hrad, srad, vrad, 0.3D); } diff --git a/core/src/main/java/com/volmit/iris/util/io/IO.java b/core/src/main/java/com/volmit/iris/util/io/IO.java index 554058244..281f08096 100644 --- a/core/src/main/java/com/volmit/iris/util/io/IO.java +++ b/core/src/main/java/com/volmit/iris/util/io/IO.java @@ -24,9 +24,13 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.volmit.iris.Iris; import com.volmit.iris.util.format.Form; +import org.apache.commons.io.function.IOConsumer; +import org.apache.commons.io.function.IOFunction; import java.io.*; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -1638,4 +1642,19 @@ public class IO { int ch2 = input2.read(); return (ch2 == -1); } + + public static void write(File file, IOFunction builder, IOConsumer action) throws IOException { + File dir = new File(file.getParentFile(), ".tmp"); + dir.mkdirs(); + dir.deleteOnExit(); + File temp = File.createTempFile("iris",".bin", dir); + try { + try (var out = builder.apply(new FileOutputStream(temp))) { + action.accept(out); + } + Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } finally { + temp.delete(); + } + } } diff --git a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 77b849272..6ec24717d 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer4; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.math.M; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.MatterSlice; @@ -84,7 +85,6 @@ public class Mantle { this.worldHeight = worldHeight; this.ioTrim = new AtomicBoolean(false); this.ioTectonicUnload = new AtomicBoolean(false); - dataFolder.mkdirs(); loadedRegions = new KMap<>(); lastUse = new KMap<>(); ioBurst = MultiBurst.burst; @@ -387,6 +387,7 @@ public class Mantle { } })); loadedRegions.clear(); + IO.delete(new File(dataFolder, ".tmp")); try { b.complete(); diff --git a/core/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/core/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index 82c259aaf..101019023 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -27,6 +27,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.CountingDataInputStream; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; import net.jpountz.lz4.LZ4BlockInputStream; @@ -222,13 +223,8 @@ public class TectonicPlate { */ public void write(File file) throws IOException { PrecisionStopwatch p = PrecisionStopwatch.start(); - File temp = File.createTempFile("iris-tectonic-plate", ".bin"); - try (DataOutputStream dos = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(temp)))) { - write(dos); - } - Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); + IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), this::write); Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName() + C.RED + " in " + Form.duration(p.getMilliseconds(), 2)); - temp.delete(); } /** diff --git a/core/src/main/java/com/volmit/iris/util/particle/FastParticle.java b/core/src/main/java/com/volmit/iris/util/particle/FastParticle.java deleted file mode 100644 index 4052dbdd2..000000000 --- a/core/src/main/java/com/volmit/iris/util/particle/FastParticle.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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.util.particle; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -/** - * Simple Bukkit Particles API with 1.7 to 1.13.2 support ! - *

- * You can find the project on GitHub - * - * @author MrMicky - */ -public final class FastParticle { - - private static final ParticleSender PARTICLE_SENDER; - - static { - if (FastReflection.optionalClass("org.bukkit.Particle$DustOptions").isPresent()) { - PARTICLE_SENDER = new ParticleSender.ParticleSender1_13(); - } else if (FastReflection.optionalClass("org.bukkit.Particle").isPresent()) { - PARTICLE_SENDER = new ParticleSender.ParticleSenderImpl(); - } else { - PARTICLE_SENDER = new ParticleSenderLegacy(); - } - } - - private FastParticle() { - throw new UnsupportedOperationException(); - } - - /* - * Worlds methods - */ - public static void spawnParticle(World world, ParticleType particle, Location location, int count) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count) { - spawnParticle(world, particle, x, y, z, count, null); - } - - public static void spawnParticle(World world, ParticleType particle, Location location, int count, T data) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count, data); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count, - T data) { - spawnParticle(world, particle, x, y, z, count, 0.0D, 0.0D, 0.0D, data); - } - - public static void spawnParticle(World world, ParticleType particle, Location location, int count, double offsetX, - double offsetY, double offsetZ) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ) { - spawnParticle(world, particle, x, y, z, count, offsetX, offsetY, offsetZ, null); - } - - public static void spawnParticle(World world, ParticleType particle, Location location, int count, - double offsetX, double offsetY, double offsetZ, T data) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, - offsetZ, data); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, T data) { - spawnParticle(world, particle, x, y, z, count, offsetX, offsetY, offsetZ, 1.0D, data); - } - - public static void spawnParticle(World world, ParticleType particle, Location location, int count, double offsetX, - double offsetY, double offsetZ, double extra) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ, extra); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, double extra) { - spawnParticle(world, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, null); - } - - public static void spawnParticle(World world, ParticleType particle, Location location, int count, - double offsetX, double offsetY, double offsetZ, double extra, T data) { - spawnParticle(world, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ, extra, data); - } - - public static void spawnParticle(World world, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, double extra, T data) { - sendParticle(world, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } - - /* - * Player methods - */ - public static void spawnParticle(Player player, ParticleType particle, Location location, int count) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count) { - spawnParticle(player, particle, x, y, z, count, null); - } - - public static void spawnParticle(Player player, ParticleType particle, Location location, int count, T data) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count, data); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count, - T data) { - spawnParticle(player, particle, x, y, z, count, 0.0D, 0.0D, 0.0D, data); - } - - public static void spawnParticle(Player player, ParticleType particle, Location location, int count, double offsetX, - double offsetY, double offsetZ) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ) { - spawnParticle(player, particle, x, y, z, count, offsetX, offsetY, offsetZ, null); - } - - public static void spawnParticle(Player player, ParticleType particle, Location location, int count, - double offsetX, double offsetY, double offsetZ, T data) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ, data); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, T data) { - spawnParticle(player, particle, x, y, z, count, offsetX, offsetY, offsetZ, 1.0D, data); - } - - public static void spawnParticle(Player player, ParticleType particle, Location location, int count, double offsetX, - double offsetY, double offsetZ, double extra) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ, extra); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, double extra) { - spawnParticle(player, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, null); - } - - public static void spawnParticle(Player player, ParticleType particle, Location location, int count, - double offsetX, double offsetY, double offsetZ, double extra, T data) { - spawnParticle(player, particle, location.getX(), location.getY(), location.getZ(), count, offsetX, offsetY, offsetZ, extra, data); - } - - public static void spawnParticle(Player player, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, double extra, T data) { - sendParticle(player, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } - - private static void sendParticle(Object receiver, ParticleType particle, double x, double y, double z, int count, - double offsetX, double offsetY, double offsetZ, double extra, Object data) { - if (!particle.isSupported()) { - throw new IllegalArgumentException("The particle '" + particle + "' is not compatible with your server version"); - } - - PARTICLE_SENDER.spawnParticle(receiver, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } -} diff --git a/core/src/main/java/com/volmit/iris/util/particle/FastReflection.java b/core/src/main/java/com/volmit/iris/util/particle/FastReflection.java deleted file mode 100644 index ee5994fb6..000000000 --- a/core/src/main/java/com/volmit/iris/util/particle/FastReflection.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.util.particle; - -import com.volmit.iris.Iris; -import org.bukkit.Bukkit; - -import java.util.Optional; - -/** - * Small reflection class to use CraftBukkit and NMS - * - * @author MrMicky - */ -public final class FastReflection { - - public static final String OBC_PACKAGE = "org.bukkit.craftbukkit"; - public static final String NMS_PACKAGE = "net.minecraft.server"; - - public static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().substring(OBC_PACKAGE.length() + 1); - - private FastReflection() { - throw new UnsupportedOperationException(); - } - - public static String nmsClassName(String className) { - return NMS_PACKAGE + '.' + VERSION + '.' + className; - } - - public static Class nmsClass(String className) throws ClassNotFoundException { - return Class.forName(nmsClassName(className)); - } - - public static Optional> nmsOptionalClass(String className) { - return optionalClass(nmsClassName(className)); - } - - public static String obcClassName(String className) { - return OBC_PACKAGE + '.' + VERSION + '.' + className; - } - - public static Class obcClass(String className) throws ClassNotFoundException { - return Class.forName(obcClassName(className)); - } - - public static Optional> obcOptionalClass(String className) { - return optionalClass(obcClassName(className)); - } - - public static Optional> optionalClass(String className) { - try { - return Optional.of(Class.forName(className)); - } catch (ClassNotFoundException e) { - Iris.reportError(e); - return Optional.empty(); - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public static Object enumValueOf(Class enumClass, String enumName) { - return Enum.valueOf((Class) enumClass, enumName.toUpperCase()); - } -} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/particle/ParticleSender.java b/core/src/main/java/com/volmit/iris/util/particle/ParticleSender.java deleted file mode 100644 index d9ac0a401..000000000 --- a/core/src/main/java/com/volmit/iris/util/particle/ParticleSender.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.util.particle; - -import com.volmit.iris.Iris; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Particle; -import org.bukkit.World; -import org.bukkit.block.data.BlockData; -import org.bukkit.entity.Player; -import org.bukkit.material.MaterialData; - -/** - * Particle sender using the Bukkit particles API for 1.9+ servers - * - * @author MrMicky - */ -@SuppressWarnings("deprecation") -interface ParticleSender { - - void spawnParticle(Object receiver, ParticleType particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, Object data); - - Object getParticle(ParticleType particle); - - boolean isValidData(Object particle, Object data); - - default double color(double color) { - return color / 255.0; - } - - class ParticleSenderImpl implements ParticleSender { - - @Override - public void spawnParticle(Object receiver, ParticleType particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, Object data) { - Particle bukkitParticle = Particle.valueOf(particle.toString()); - - if (data instanceof Color) { - if (particle.getDataType() == Color.class) { - Color color = (Color) data; - count = 0; - offsetX = color(color.getRed()); - offsetY = color(color.getGreen()); - offsetZ = color(color.getBlue()); - extra = 1.0; - } - data = null; - } - - if (receiver instanceof World) { - ((World) receiver).spawnParticle(bukkitParticle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } else if (receiver instanceof Player) { - ((Player) receiver).spawnParticle(bukkitParticle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } - } - - @Override - public Particle getParticle(ParticleType particle) { - try { - return Particle.valueOf(particle.toString()); - } catch (IllegalArgumentException e) { - Iris.reportError(e); - return null; - } - } - - @Override - public boolean isValidData(Object particle, Object data) { - return isValidDataBukkit((Particle) particle, data); - } - - public boolean isValidDataBukkit(Particle particle, Object data) { - return particle.getDataType() == Void.class || particle.getDataType().isInstance(data); - } - } - - class ParticleSender1_13 extends ParticleSenderImpl { - @Override - public void spawnParticle(Object receiver, ParticleType particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, Object data) { - Particle bukkitParticle = Particle.valueOf(particle.toString()); - - if (bukkitParticle.getDataType() == Particle.DustOptions.class) { - if (data instanceof Color) { - data = new Particle.DustOptions((Color) data, 1); - } else if (data == null) { - data = new Particle.DustOptions(Color.RED, 1); - } - } else if (bukkitParticle.getDataType() == BlockData.class && data instanceof MaterialData) { - data = Bukkit.createBlockData(((MaterialData) data).getItemType()); - } - - super.spawnParticle(receiver, particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data); - } - - @Override - public boolean isValidDataBukkit(Particle particle, Object data) { - if (particle.getDataType() == Particle.DustOptions.class && data instanceof Color) { - return true; - } - - if (particle.getDataType() == BlockData.class && data instanceof MaterialData) { - return true; - } - - return super.isValidDataBukkit(particle, data); - } - } -} diff --git a/core/src/main/java/com/volmit/iris/util/particle/ParticleSenderLegacy.java b/core/src/main/java/com/volmit/iris/util/particle/ParticleSenderLegacy.java deleted file mode 100644 index 1668de313..000000000 --- a/core/src/main/java/com/volmit/iris/util/particle/ParticleSenderLegacy.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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.util.particle; - -import com.volmit.iris.Iris; -import org.bukkit.Color; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -/** - * Legacy particle sender with NMS for 1.7/1.8 servers - * - * @author MrMicky - */ -@SuppressWarnings({"deprecation", "JavaReflectionInvocation"}) -class ParticleSenderLegacy implements ParticleSender { - - private static final boolean SERVER_IS_1_8; - - private static final Constructor PACKET_PARTICLE; - private static final Class ENUM_PARTICLE; - - private static final Method WORLD_GET_HANDLE; - private static final Method WORLD_SEND_PARTICLE; - - private static final Method PLAYER_GET_HANDLE; - private static final Field PLAYER_CONNECTION; - private static final Method SEND_PACKET; - private static final int[] EMPTY = new int[0]; - - static { - ENUM_PARTICLE = FastReflection.nmsOptionalClass("EnumParticle").orElse(null); - SERVER_IS_1_8 = ENUM_PARTICLE != null; - - try { - Class packetParticleClass = FastReflection.nmsClass("PacketPlayOutWorldParticles"); - Class playerClass = FastReflection.nmsClass("EntityPlayer"); - Class playerConnectionClass = FastReflection.nmsClass("PlayerConnection"); - Class worldClass = FastReflection.nmsClass("WorldServer"); - Class entityPlayerClass = FastReflection.nmsClass("EntityPlayer"); - - Class craftPlayerClass = FastReflection.obcClass("entity.CraftPlayer"); - Class craftWorldClass = FastReflection.obcClass("CraftWorld"); - - if (SERVER_IS_1_8) { - PACKET_PARTICLE = packetParticleClass.getConstructor(ENUM_PARTICLE, boolean.class, float.class, - float.class, float.class, float.class, float.class, float.class, float.class, int.class, - int[].class); - WORLD_SEND_PARTICLE = worldClass.getDeclaredMethod("sendParticles", entityPlayerClass, ENUM_PARTICLE, - boolean.class, double.class, double.class, double.class, int.class, double.class, double.class, - double.class, double.class, int[].class); - } else { - PACKET_PARTICLE = packetParticleClass.getConstructor(String.class, float.class, float.class, float.class, - float.class, float.class, float.class, float.class, int.class); - WORLD_SEND_PARTICLE = worldClass.getDeclaredMethod("a", String.class, double.class, double.class, - double.class, int.class, double.class, double.class, double.class, double.class); - } - - WORLD_GET_HANDLE = craftWorldClass.getDeclaredMethod("getHandle"); - PLAYER_GET_HANDLE = craftPlayerClass.getDeclaredMethod("getHandle"); - PLAYER_CONNECTION = playerClass.getField("playerConnection"); - SEND_PACKET = playerConnectionClass.getMethod("sendPacket", FastReflection.nmsClass("Packet")); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); - } - } - - @Override - public void spawnParticle(Object receiver, ParticleType particle, double x, double y, double z, int count, double offsetX, double offsetY, - double offsetZ, double extra, Object data) { - try { - int[] datas = toData(particle, data); - - if (data instanceof Color) { - if (particle.getDataType() == Color.class) { - Color color = (Color) data; - count = 0; - offsetX = color(color.getRed()); - offsetY = color(color.getGreen()); - offsetZ = color(color.getBlue()); - extra = 1.0; - } - } - - if (receiver instanceof World) { - Object worldServer = WORLD_GET_HANDLE.invoke(receiver); - - if (SERVER_IS_1_8) { - WORLD_SEND_PARTICLE.invoke(worldServer, null, getEnumParticle(particle), true, x, y, z, count, offsetX, offsetY, offsetZ, extra, datas); - } else { - String particleName = particle.getLegacyName() + (datas.length != 2 ? "" : "_" + datas[0] + "_" + datas[1]); - WORLD_SEND_PARTICLE.invoke(worldServer, particleName, x, y, z, count, offsetX, offsetY, offsetZ, extra); - } - } else if (receiver instanceof Player) { - Object packet; - - if (SERVER_IS_1_8) { - packet = PACKET_PARTICLE.newInstance(getEnumParticle(particle), true, (float) x, (float) y, - (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count, datas); - } else { - String particleName = particle.getLegacyName() + (datas.length != 2 ? "" : "_" + datas[0] + "_" + datas[1]); - packet = PACKET_PARTICLE.newInstance(particleName, (float) x, (float) y, (float) z, - (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); - } - - Object entityPlayer = PLAYER_GET_HANDLE.invoke(receiver); - Object playerConnection = PLAYER_CONNECTION.get(entityPlayer); - SEND_PACKET.invoke(playerConnection, packet); - } - } catch (ReflectiveOperationException e) { - Iris.reportError(e); - throw new RuntimeException(e); - } - } - - @Override - public boolean isValidData(Object particle, Object data) { - return true; - } - - @Override - public Object getParticle(ParticleType particle) { - if (!SERVER_IS_1_8) { - return particle.getLegacyName(); - } - - try { - return getEnumParticle(particle); - } catch (IllegalArgumentException e) { - Iris.reportError(e); - return null; - } - } - - private Object getEnumParticle(ParticleType particleType) { - return FastReflection.enumValueOf(ENUM_PARTICLE, particleType.toString()); - } - - private int[] toData(ParticleType particle, Object data) { - Class dataType = particle.getDataType(); - if (dataType == ItemStack.class) { - if (!(data instanceof ItemStack itemStack)) { - return SERVER_IS_1_8 ? new int[2] : new int[]{1, 0}; - } - - return new int[]{itemStack.getType().getId(), itemStack.getDurability()}; - } - - if (dataType == MaterialData.class) { - if (!(data instanceof MaterialData materialData)) { - return SERVER_IS_1_8 ? new int[1] : new int[]{1, 0}; - } - - if (SERVER_IS_1_8) { - return new int[]{materialData.getItemType().getId() + (materialData.getData() << 12)}; - } else { - return new int[]{materialData.getItemType().getId(), materialData.getData()}; - } - } - - return EMPTY; - } -} diff --git a/core/src/main/java/com/volmit/iris/util/particle/ParticleType.java b/core/src/main/java/com/volmit/iris/util/particle/ParticleType.java deleted file mode 100644 index 25da1bd75..000000000 --- a/core/src/main/java/com/volmit/iris/util/particle/ParticleType.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.util.particle; - -import com.volmit.iris.Iris; -import org.bukkit.Color; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; - -/** - * @author MrMicky - */ -@SuppressWarnings("deprecation") -public enum ParticleType { - - // 1.7+ - EXPLOSION_NORMAL("explode", "poof"), - EXPLOSION_LARGE("largeexplode", "explosion"), - EXPLOSION_HUGE("hugeexplosion", "explosion_emitter"), - FIREWORKS_SPARK("fireworksSpark", "firework"), - WATER_BUBBLE("bubble", "bubble"), - WATER_SPLASH("splash", "splash"), - WATER_WAKE("wake", "fishing"), - SUSPENDED("suspended", "underwater"), - SUSPENDED_DEPTH("depthsuspend", "underwater"), - CRIT("crit", "crit"), - CRIT_MAGIC("magicCrit", "enchanted_hit"), - SMOKE_NORMAL("smoke", "smoke"), - SMOKE_LARGE("largesmoke", "large_smoke"), - SPELL("spell", "effect"), - SPELL_INSTANT("instantSpell", "instant_effect"), - SPELL_MOB("mobSpell", "entity_effect"), - SPELL_MOB_AMBIENT("mobSpellAmbient", "ambient_entity_effect"), - SPELL_WITCH("witchMagic", "witch"), - DRIP_WATER("dripWater", "dripping_water"), - DRIP_LAVA("dripLava", "dripping_lava"), - VILLAGER_ANGRY("angryVillager", "angry_villager"), - VILLAGER_HAPPY("happyVillager", "happy_villager"), - TOWN_AURA("townaura", "mycelium"), - NOTE("note", "note"), - PORTAL("portal", "portal"), - ENCHANTMENT_TABLE("enchantmenttable", "enchant"), - FLAME("flame", "flame"), - LAVA("lava", "lava"), - // FOOTSTEP("footstep", null), - CLOUD("cloud", "cloud"), - REDSTONE("reddust", "dust"), - SNOWBALL("snowballpoof", "item_snowball"), - SNOW_SHOVEL("snowshovel", "item_snowball"), - SLIME("slime", "item_slime"), - HEART("heart", "heart"), - ITEM_CRACK("iconcrack", "item"), - BLOCK_CRACK("blockcrack", "block"), - BLOCK_DUST("blockdust", "block"), - - // 1.8+ - BARRIER("barrier", "barrier", 8), - WATER_DROP("droplet", "rain", 8), - MOB_APPEARANCE("mobappearance", "elder_guardian", 8), - // ITEM_TAKE("take", null, 8), - - // 1.9+ - DRAGON_BREATH("dragonbreath", "dragon_breath", 9), - END_ROD("endRod", "end_rod", 9), - DAMAGE_INDICATOR("damageIndicator", "damage_indicator", 9), - SWEEP_ATTACK("sweepAttack", "sweep_attack", 9), - - // 1.10+ - FALLING_DUST("fallingdust", "falling_dust", 10), - - // 1.11+ - TOTEM("totem", "totem_of_undying", 11), - SPIT("spit", "spit", 11), - - // 1.13+ - SQUID_INK(13), - BUBBLE_POP(13), - CURRENT_DOWN(13), - BUBBLE_COLUMN_UP(13), - NAUTILUS(13), - DOLPHIN(13), - - // 1.14+ - SNEEZE(14), - CAMPFIRE_COSY_SMOKE(14), - CAMPFIRE_SIGNAL_SMOKE(14), - COMPOSTER(14), - FLASH(14), - FALLING_LAVA(14), - LANDING_LAVA(14), - FALLING_WATER(14), - - // 1.15+ - DRIPPING_HONEY(15), - FALLING_HONEY(15), - LANDING_HONEY(15), - FALLING_NECTAR(15); - - private static final int SERVER_VERSION_ID; - - static { - String ver = FastReflection.VERSION; - SERVER_VERSION_ID = ver.charAt(4) == '_' ? Character.getNumericValue(ver.charAt(3)) : Integer.parseInt(ver.substring(3, 5)); - } - - private final String legacyName; - private final String name; - private final int minimumVersion; - - // 1.7 particles - ParticleType(String legacyName, String name) { - this(legacyName, name, -1); - } - - // 1.13+ particles - ParticleType(int minimumVersion) { - this.legacyName = null; - this.name = name().toLowerCase(); - this.minimumVersion = minimumVersion; - } - - // 1.8-1.12 particles - ParticleType(String legacyName, String name, int minimumVersion) { - this.legacyName = legacyName; - this.name = name; - this.minimumVersion = minimumVersion; - } - - public static ParticleType getParticle(String particleName) { - try { - return ParticleType.valueOf(particleName.toUpperCase()); - } catch (IllegalArgumentException e) { - Iris.reportError(e); - for (ParticleType particle : values()) { - if (particle.getName().equalsIgnoreCase(particleName)) { - return particle; - } - - if (particle.hasLegacyName() && particle.getLegacyName().equalsIgnoreCase(particleName)) { - return particle; - } - } - } - return null; - } - - public boolean hasLegacyName() { - return legacyName != null; - } - - public String getLegacyName() { - if (!hasLegacyName()) { - throw new IllegalStateException("Particle " + name() + " don't have legacy name"); - } - return legacyName; - } - - public String getName() { - return name; - } - - public boolean isSupported() { - return minimumVersion <= 0 || SERVER_VERSION_ID >= minimumVersion; - } - - public Class getDataType() { - return switch (this) { - case ITEM_CRACK -> ItemStack.class; - case BLOCK_CRACK, BLOCK_DUST, FALLING_DUST -> - //noinspection deprecation - MaterialData.class; - case REDSTONE -> Color.class; - default -> Void.class; - }; - } -} diff --git a/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java index 217b44054..dccb95ce7 100644 --- a/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java +++ b/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java @@ -264,7 +264,7 @@ public class VolmitSender implements CommandSender { private Component createNoPrefixComponent(String message) { if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) { String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(message)); - return MiniMessage.miniMessage().deserialize(t); + return MiniMessage.miniMessage().deserialize(C.mini(t)); } String t = C.translateAlternateColorCodes('&', message); @@ -273,13 +273,13 @@ public class VolmitSender implements CommandSender { } private Component createNoPrefixComponentNoProcessing(String message) { - return MiniMessage.builder().postProcessor(c -> c).build().deserialize(message); + return MiniMessage.builder().postProcessor(c -> c).build().deserialize(C.mini(message)); } private Component createComponent(String message) { if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) { String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message)); - return MiniMessage.miniMessage().deserialize(t); + return MiniMessage.miniMessage().deserialize(C.mini(t)); } String t = C.translateAlternateColorCodes('&', getTag() + message); @@ -290,11 +290,11 @@ public class VolmitSender implements CommandSender { private Component createComponentRaw(String message) { if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) { String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message)); - return MiniMessage.miniMessage().deserialize(t); + return MiniMessage.miniMessage().deserialize(C.mini(t)); } String t = C.translateAlternateColorCodes('&', getTag() + message); - return MiniMessage.miniMessage().deserialize(t); + return MiniMessage.miniMessage().deserialize(C.mini(t)); } public void showWaiting(String passive, CompletableFuture f) { diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/Looper.java b/core/src/main/java/com/volmit/iris/util/scheduling/Looper.java index e5be20b84..72ba9ff03 100644 --- a/core/src/main/java/com/volmit/iris/util/scheduling/Looper.java +++ b/core/src/main/java/com/volmit/iris/util/scheduling/Looper.java @@ -36,7 +36,6 @@ public abstract class Looper extends Thread { //noinspection BusyWait Thread.sleep(m); } catch (InterruptedException e) { - Iris.reportError(e); break; } catch (Throwable e) { Iris.reportError(e); diff --git a/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java b/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java new file mode 100644 index 000000000..a338ea6ce --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java @@ -0,0 +1,41 @@ +package com.volmit.iris.util.sentry; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.volmit.iris.util.collection.KMap; +import io.sentry.Attachment; +import org.bukkit.Bukkit; + +import java.nio.charset.StandardCharsets; +import java.util.concurrent.Callable; + +public class Attachments { + private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); + public static final Attachment PLUGINS = jsonProvider(Attachments::plugins, "plugins.json"); + + public static Attachment json(Object object, String name) { + return new Attachment(GSON.toJson(object).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true); + } + + public static Attachment jsonProvider(Callable object, String name) { + return new Attachment(() -> GSON.toJson(object.call()).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true); + } + + private static KMap plugins() { + KMap enabled = new KMap<>(); + KMap disabled = new KMap<>(); + + var pm = Bukkit.getPluginManager(); + for (var plugin : pm.getPlugins()) { + if (plugin.isEnabled()) { + enabled.put(plugin.getName(), plugin.getDescription().getVersion()); + } else { + disabled.put(plugin.getName(), plugin.getDescription().getVersion()); + } + } + + return new KMap() + .qput("enabled", enabled) + .qput("disabled", disabled); + } +} diff --git a/core/src/main/java/com/volmit/iris/util/sentry/IrisLogger.java b/core/src/main/java/com/volmit/iris/util/sentry/IrisLogger.java new file mode 100644 index 000000000..e51d407c5 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/sentry/IrisLogger.java @@ -0,0 +1,47 @@ +package com.volmit.iris.util.sentry; + +import com.volmit.iris.Iris; +import io.sentry.ILogger; +import io.sentry.SentryLevel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class IrisLogger implements ILogger { + @Override + public void log(@NotNull SentryLevel level, @NotNull String message, @Nullable Object... args) { + Iris.msg(String.format("%s: %s", level, String.format(message, args))); + } + + @Override + public void log(@NotNull SentryLevel level, @NotNull String message, @Nullable Throwable throwable) { + if (throwable == null) { + log(level, message); + } else { + Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); + } + } + + @Override + public void log(@NotNull SentryLevel level, @Nullable Throwable throwable, @NotNull String message, @Nullable Object... args) { + if (throwable == null) { + log(level, message, args); + } else { + Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable))); + } + } + + @Override + public boolean isEnabled(@Nullable SentryLevel level) { + return true; + } + + private @NotNull String captureStackTrace(@NotNull Throwable throwable) { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + throwable.printStackTrace(printWriter); + return stringWriter.toString(); + } +} diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index aa75fc983..d742560ac 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -25,5 +25,5 @@ libraries: commands: iris: aliases: [ ir, irs ] -api-version: '${apiversion}' +api-version: '${apiVersion}' hotload-dependencies: false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2..e6441136f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 48c0a02ca..ff23a68d7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c78733..1aa94a426 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f93..7101f8e46 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle.kts similarity index 74% rename from settings.gradle rename to settings.gradle.kts index 9315a1131..c45462895 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -23,19 +23,19 @@ pluginManagement { } } plugins { - id "org.gradle.toolchains.foojay-resolver-convention" version "0.8.0" + id ("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } -rootProject.name = 'Iris' +rootProject.name = "Iris" -include(':core') +include(":core") include( - ':nms:v1_21_R4', - ':nms:v1_21_R3', - ':nms:v1_21_R2', - ':nms:v1_21_R1', - ':nms:v1_20_R4', - ':nms:v1_20_R3', - ':nms:v1_20_R2', - ':nms:v1_20_R1', + ":nms:v1_21_R4", + ":nms:v1_21_R3", + ":nms:v1_21_R2", + ":nms:v1_21_R1", + ":nms:v1_20_R4", + ":nms:v1_20_R3", + ":nms:v1_20_R2", + ":nms:v1_20_R1", ) \ No newline at end of file