mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 23:47:21 +00:00
Merge branch 'dev' into feat/byte_buddy
# Conflicts: # build.gradle # core/src/main/java/com/volmit/iris/Iris.java
This commit is contained in:
commit
4c3f95b0e1
291
build.gradle
291
build.gradle
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.<String, Integer>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)
|
|
276
build.gradle.kts
Normal file
276
build.gradle.kts
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<String, Int>()
|
||||||
|
nmsBindings.forEach { key, value ->
|
||||||
|
project(":nms:$key") {
|
||||||
|
apply<JavaPlugin>()
|
||||||
|
apply<NMSToolsPlugin>()
|
||||||
|
|
||||||
|
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>("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<Copy>("iris") {
|
||||||
|
group = "iris"
|
||||||
|
dependsOn("jar")
|
||||||
|
from(layout.buildDirectory.file("libs/Iris-${project.version}.jar"))
|
||||||
|
into(layout.buildDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
register<Copy>("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<Download>("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<JavaPlugin>()
|
||||||
|
|
||||||
|
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<Jar>("sourcesJar") {
|
||||||
|
archiveClassifier.set("sources")
|
||||||
|
from(sourceSets.main.map { it.allSource })
|
||||||
|
}
|
||||||
|
|
||||||
|
register<Jar>("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<Copy>("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<Copy>("build$name") {
|
||||||
|
group = "development"
|
||||||
|
outputs.upToDateWhen { false }
|
||||||
|
dependsOn("iris")
|
||||||
|
from(layout.buildDirectory.file("Iris-${project.version}.jar"))
|
||||||
|
into(file(path))
|
||||||
|
rename { "Iris.jar" }
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
151
core/build.gradle.kts
Normal file
151
core/build.gradle.kts
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
@ -43,6 +43,7 @@ import com.volmit.iris.core.safeguard.UtilsSFG;
|
|||||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
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.exceptions.IrisException;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
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.J;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
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.papermc.lib.PaperLib;
|
||||||
|
import io.sentry.Sentry;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||||
@ -391,6 +395,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void reportError(Throwable e) {
|
public static void reportError(Throwable e) {
|
||||||
|
Sentry.captureException(e);
|
||||||
if (IrisSettings.get().getGeneral().isDebug()) {
|
if (IrisSettings.get().getGeneral().isDebug()) {
|
||||||
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
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;
|
instance = this;
|
||||||
services = new KMap<>();
|
services = new KMap<>();
|
||||||
setupAudience();
|
setupAudience();
|
||||||
|
setupSentry();
|
||||||
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||||
@ -524,6 +530,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +548,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (IrisException e) {
|
} catch (IrisException e) {
|
||||||
e.printStackTrace();
|
reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -941,4 +948,35 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
return -1;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public class IrisSettings {
|
|||||||
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
||||||
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
||||||
private IrisSettingsPregen pregen = new IrisSettingsPregen();
|
private IrisSettingsPregen pregen = new IrisSettingsPregen();
|
||||||
|
private IrisSettingsSentry sentry = new IrisSettingsSentry();
|
||||||
|
|
||||||
public static int getThreadCount(int c) {
|
public static int getThreadCount(int c) {
|
||||||
return switch (c) {
|
return switch (c) {
|
||||||
@ -131,7 +132,7 @@ public class IrisSettings {
|
|||||||
public boolean markerEntitySpawningSystem = true;
|
public boolean markerEntitySpawningSystem = true;
|
||||||
public boolean effectSystem = true;
|
public boolean effectSystem = true;
|
||||||
public boolean worldEditWandCUI = true;
|
public boolean worldEditWandCUI = true;
|
||||||
public boolean globalPregenCache = true;
|
public boolean globalPregenCache = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -222,6 +223,12 @@ public class IrisSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class IrisSettingsSentry {
|
||||||
|
public boolean disableAutoReporting = false;
|
||||||
|
public boolean debug = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGUI {
|
public static class IrisSettingsGUI {
|
||||||
public boolean useServerLaunchedGuis = true;
|
public boolean useServerLaunchedGuis = true;
|
||||||
|
@ -26,6 +26,7 @@ import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
|||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
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.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
@ -71,6 +72,13 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
.engineStatus(sender());
|
.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")
|
@Decree(description = "Test")
|
||||||
public void dumpThreads() {
|
public void dumpThreads() {
|
||||||
try {
|
try {
|
||||||
|
@ -241,7 +241,8 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
|
|
||||||
|
|
||||||
Location[] b = WandSVC.getCuboid(player());
|
Location[] b = WandSVC.getCuboid(player());
|
||||||
if (b == null) {
|
if (b == null || b[0] == null || b[1] == null) {
|
||||||
|
sender().sendMessage("No area selected.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Location a1 = b[0].clone();
|
Location a1 = b[0].clone();
|
||||||
@ -417,6 +418,10 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Location[] b = WandSVC.getCuboid(player());
|
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 a1 = b[0].clone();
|
||||||
Location a2 = b[1].clone();
|
Location a2 = b[1].clone();
|
||||||
Direction d = Direction.closest(player().getLocation().getDirection()).reverse();
|
Direction d = Direction.closest(player().getLocation().getDirection()).reverse();
|
||||||
@ -477,6 +482,10 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Location[] b = WandSVC.getCuboid(player());
|
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 a1 = b[0].clone();
|
||||||
Location a2 = b[1].clone();
|
Location a2 = b[1].clone();
|
||||||
Location a1x = b[0].clone();
|
Location a1x = b[0].clone();
|
||||||
@ -524,6 +533,10 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Location[] b = WandSVC.getCuboid(player());
|
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[0].add(new Vector(0, 1, 0));
|
||||||
b[1].add(new Vector(0, 1, 0));
|
b[1].add(new Vector(0, 1, 0));
|
||||||
Location a1 = b[0].clone();
|
Location a1 = b[0].clone();
|
||||||
|
@ -47,6 +47,7 @@ public class WorldEditLink {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("Could not get selection");
|
Iris.error("Could not get selection");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
Iris.reportError(e);
|
||||||
active.reset();
|
active.reset();
|
||||||
active.aquire(() -> false);
|
active.aquire(() -> false);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +300,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Iris.error("Failed to create loader! " + registrant.getCanonicalName());
|
Iris.error("Failed to create loader! " + registrant.getCanonicalName());
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import lombok.ToString;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -240,8 +241,10 @@ public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
|
|||||||
for (String i : s) {
|
for (String i : s) {
|
||||||
burst.queue(() -> {
|
burst.queue(() -> {
|
||||||
T t = load(i);
|
T t = load(i);
|
||||||
|
if (t == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (t != null) {
|
synchronized (m) {
|
||||||
m.add(t);
|
m.add(t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -109,6 +109,7 @@ public class ChunkUpdater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}, 0, 3, TimeUnit.SECONDS);
|
}, 0, 3, TimeUnit.SECONDS);
|
||||||
@ -314,6 +315,7 @@ public class ChunkUpdater {
|
|||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.util.data.Varint;
|
import com.volmit.iris.util.data.Varint;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.parallel.HyperLock;
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
@ -70,6 +71,7 @@ class PregenCacheImpl implements PregenCache {
|
|||||||
return new Plate(key, in);
|
return new Plate(key, in);
|
||||||
} catch (IOException e){
|
} catch (IOException e){
|
||||||
Iris.error("Failed to read pregen cache " + file);
|
Iris.error("Failed to read pregen cache " + file);
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new Plate(key);
|
return new Plate(key);
|
||||||
}
|
}
|
||||||
@ -82,10 +84,11 @@ class PregenCacheImpl implements PregenCache {
|
|||||||
hyperLock.lock(plate.pos.x, plate.pos.z);
|
hyperLock.lock(plate.pos.x, plate.pos.z);
|
||||||
try {
|
try {
|
||||||
File file = fileForPlate(plate.pos);
|
File file = fileForPlate(plate.pos);
|
||||||
try (var out = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(file)))) {
|
try {
|
||||||
plate.write(out);
|
IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), plate::write);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Iris.error("Failed to write pregen cache " + file);
|
Iris.error("Failed to write pregen cache " + file);
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -157,7 +157,10 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
} catch (Throwable e) {
|
} 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("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");
|
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;
|
return 0;
|
||||||
});
|
});
|
||||||
@ -173,6 +176,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
method.invoke(pool, i);
|
method.invoke(pool, i);
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
Iris.error("Failed to reset worker threads");
|
Iris.error("Failed to reset worker threads");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -201,6 +205,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
}).get();
|
}).get();
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -219,6 +224,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
public void generate(int x, int z, PregenListener listener) {
|
public void generate(int x, int z, PregenListener listener) {
|
||||||
PaperLib.getChunkAtAsync(world, x, z, true, urgent)
|
PaperLib.getChunkAtAsync(world, x, z, true, urgent)
|
||||||
.exceptionally(e -> {
|
.exceptionally(e -> {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
|
@ -20,5 +20,15 @@ public class IrisSafeguard {
|
|||||||
Iris.instance.splash();
|
Iris.instance.splash();
|
||||||
UtilsSFG.splash();
|
UtilsSFG.splash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String mode() {
|
||||||
|
if (unstablemode) {
|
||||||
|
return "unstable";
|
||||||
|
} else if (warningmode) {
|
||||||
|
return "warning";
|
||||||
|
} else {
|
||||||
|
return "stable";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,11 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
private static final Cache<String, PregenCache> REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build();
|
private static final Cache<String, PregenCache> REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build();
|
||||||
private final KMap<String, PregenCache> globalCache = new KMap<>();
|
private final KMap<String, PregenCache> globalCache = new KMap<>();
|
||||||
private transient boolean lastState;
|
private transient boolean lastState;
|
||||||
|
private static boolean disabled = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
disabled = false;
|
||||||
lastState = !IrisSettings.get().getWorld().isGlobalPregenCache();
|
lastState = !IrisSettings.get().getWorld().isGlobalPregenCache();
|
||||||
if (lastState) return;
|
if (lastState) return;
|
||||||
Bukkit.getWorlds().forEach(this::createCache);
|
Bukkit.getWorlds().forEach(this::createCache);
|
||||||
@ -33,7 +35,8 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
globalCache.values().forEach(PregenCache::write);
|
disabled = true;
|
||||||
|
globalCache.qclear((world, cache) -> cache.write());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -99,6 +102,7 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PregenCache createDefault0(String worldName) {
|
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();
|
return PregenCache.create(new File(Bukkit.getWorldContainer(), String.join(File.separator, worldName, "iris", "pregen"))).sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ public class IrisEngineSVC implements IrisService {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine.getMantle().trim(tectonicLimit.get() / worlds.size());
|
engine.getMantle().trim(tectonicLimit());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
Iris.error("EngineSVC: Failed to trim for " + name);
|
Iris.error("EngineSVC: Failed to trim for " + name);
|
||||||
@ -204,7 +204,7 @@ public class IrisEngineSVC implements IrisService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
long unloadStart = System.currentTimeMillis();
|
long unloadStart = System.currentTimeMillis();
|
||||||
int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / worlds.size());
|
int count = engine.getMantle().unloadTectonicPlate(tectonicLimit());
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2));
|
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
|
@Synchronized
|
||||||
private void close() {
|
private void close() {
|
||||||
if (closed) return;
|
if (closed) return;
|
||||||
|
@ -51,6 +51,7 @@ import org.bukkit.util.Vector;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
@ -80,6 +81,8 @@ public class WandSVC implements IrisService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Location[] f = getCuboid(p);
|
Location[] f = getCuboid(p);
|
||||||
|
if (f == null || f[0] == null || f[1] == null)
|
||||||
|
return null;
|
||||||
Cuboid c = new Cuboid(f[0], f[1]);
|
Cuboid c = new Cuboid(f[0], f[1]);
|
||||||
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
|
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) {
|
public static Location stringToLocation(String s) {
|
||||||
try {
|
try {
|
||||||
String[] f = s.split("\\Q in \\E");
|
String[] f = s.split("\\Q in \\E");
|
||||||
|
if (f.length != 2) return null;
|
||||||
String[] g = f[0].split("\\Q,\\E");
|
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]));
|
return new Location(Bukkit.getWorld(f[1]), Integer.parseInt(g[0]), Integer.parseInt(g[1]), Integer.parseInt(g[2]));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
@ -357,6 +362,7 @@ public class WandSVC implements IrisService {
|
|||||||
try {
|
try {
|
||||||
if ((IrisSettings.get().getWorld().worldEditWandCUI && isHoldingWand(p)) || isWand(p.getInventory().getItemInMainHand())) {
|
if ((IrisSettings.get().getWorld().worldEditWandCUI && isHoldingWand(p)) || isWand(p.getInventory().getItemInMainHand())) {
|
||||||
Location[] d = getCuboid(p);
|
Location[] d = getCuboid(p);
|
||||||
|
if (d == null || d[0] == null || d[1] == null) return;
|
||||||
new WandSelection(new Cuboid(d[0], d[1]), p).draw();
|
new WandSelection(new Cuboid(d[0], d[1]), p).draw();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -78,7 +78,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -457,14 +456,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = nitems.length; i > 1; i--) {
|
||||||
try {
|
int j = rng.nextInt(i);
|
||||||
Arrays.parallelSort(nitems, (a, b) -> rng.nextInt());
|
ItemStack tmp = nitems[i - 1];
|
||||||
break;
|
nitems[i - 1] = nitems[j];
|
||||||
} catch (Throwable e) {
|
nitems[j] = tmp;
|
||||||
Iris.reportError(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory.setContents(nitems);
|
inventory.setContents(nitems);
|
||||||
|
@ -47,9 +47,7 @@ public class EnginePlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
sample();
|
if (sample() || !IrisSettings.get().getWorld().isEffectSystem())
|
||||||
|
|
||||||
if (!IrisSettings.get().getWorld().isEffectSystem())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
J.a(() -> {
|
J.a(() -> {
|
||||||
@ -81,22 +79,22 @@ public class EnginePlayer {
|
|||||||
return M.ms() - lastSample;
|
return M.ms() - lastSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sample() {
|
public boolean sample() {
|
||||||
|
Location current = player.getLocation().clone();
|
||||||
|
if (current.getWorld() != engine.getWorld().realWorld())
|
||||||
|
return true;
|
||||||
try {
|
try {
|
||||||
if (ticksSinceLastSample() > 55 && player.getLocation().distanceSquared(lastLocation) > 9 * 9) {
|
if (ticksSinceLastSample() > 55 && current.distanceSquared(lastLocation) > 9 * 9) {
|
||||||
lastLocation = player.getLocation().clone();
|
lastLocation = current;
|
||||||
lastSample = M.ms();
|
lastSample = M.ms();
|
||||||
sampleBiomeRegion();
|
biome = engine.getBiome(current);
|
||||||
|
region = engine.getRegion(current);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
|
|
||||||
private void sampleBiomeRegion() {
|
|
||||||
Location l = player.getLocation();
|
|
||||||
biome = engine.getBiome(l);
|
|
||||||
region = engine.getRegion(l);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,21 +58,21 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
private void carve(IrisCarving carving, MantleWriter writer, RNG rng, int cx, int cz) {
|
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() {
|
private int computeRadius() {
|
||||||
var dimension = getDimension();
|
var dimension = getDimension();
|
||||||
int max = 0;
|
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)) {
|
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)) {
|
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;
|
return max;
|
||||||
|
@ -61,21 +61,25 @@ public class IrisCarving {
|
|||||||
|
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) {
|
public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z, int depth) {
|
||||||
doCarving(writer, rng, engine, x, y, z, -1);
|
doCarving(writer, rng, engine, x, y, z, depth, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@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()) {
|
if (caves.isNotEmpty()) {
|
||||||
for (IrisCavePlacer i : caves) {
|
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()) {
|
if (ravines.isNotEmpty()) {
|
||||||
for (IrisRavinePlacer i : ravines) {
|
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 max = 0;
|
||||||
|
int nextRecursion = recursion + 1;
|
||||||
|
|
||||||
for (IrisCavePlacer i : caves) {
|
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) {
|
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()) {
|
if (elipsoids.isNotEmpty()) {
|
||||||
|
@ -66,10 +66,10 @@ public class IrisCave extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) {
|
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());
|
double girth = getWorm().getGirth().get(rng, x, z, engine.getData());
|
||||||
KList<IrisPosition> points = getWorm().generate(rng, engine.getData(), writer, verticalRange, x, y, z, (at) -> {
|
KList<IrisPosition> 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());
|
int h = Math.min(Math.max(highestWater, waterHint), engine.getDimension().getFluidHeight());
|
||||||
|
|
||||||
for (IrisPosition i : points) {
|
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);
|
MatterCavern c = new MatterCavern(true, customBiome, (byte) 0);
|
||||||
@ -108,7 +108,7 @@ public class IrisCave extends IrisRegistrant {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxSize(IrisData data) {
|
public int getMaxSize(IrisData data, int depth) {
|
||||||
return getWorm().getMaxDistance() + fork.getMaxRange(data);
|
return getWorm().getMaxDistance() + fork.getMaxRange(data, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,10 @@ public class IrisCavePlacer implements IRare {
|
|||||||
@Desc("The cave to place")
|
@Desc("The cave to place")
|
||||||
@RegistryListResource(IrisCave.class)
|
@RegistryListResource(IrisCave.class)
|
||||||
private String cave;
|
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")
|
@Desc("If set to true, this cave is allowed to break the surface")
|
||||||
private boolean breakSurface = true;
|
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.")
|
@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) {
|
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()) {
|
if (fail.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,18 +96,18 @@ public class IrisCavePlacer implements IRare {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail.set(true);
|
fail.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize(IrisData data) {
|
public int getSize(IrisData data, int depth) {
|
||||||
IrisCave cave = getRealCave(data);
|
IrisCave cave = getRealCave(data);
|
||||||
|
|
||||||
if (cave != null) {
|
if (cave != null) {
|
||||||
return cave.getMaxSize(data);
|
return cave.getMaxSize(data, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 32;
|
return 32;
|
||||||
|
@ -93,10 +93,10 @@ public class IrisRavine extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) {
|
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<IrisPosition> pos = getWorm().generate(rng, engine.getData(), writer, null, x, y, z, (at) -> {
|
KList<IrisPosition> pos = getWorm().generate(rng, engine.getData(), writer, null, x, y, z, (at) -> {
|
||||||
});
|
});
|
||||||
CNG dg = depthStyle.getGenerator().createNoCache(rng, engine.getData());
|
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 width = (int) Math.round(bw.fitDouble(baseWidthStyle.getMin(), baseWidthStyle.getMax(), p.getX(), p.getZ()));
|
||||||
int surface = (int) Math.round(rsurface - depth * 0.45);
|
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--) {
|
for (int i = surface + depth; i >= surface; i--) {
|
||||||
if (i % ribThickness == 0) {
|
if (i % ribThickness == 0) {
|
||||||
@ -184,7 +184,7 @@ public class IrisRavine extends IrisRegistrant {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxSize(IrisData data) {
|
public int getMaxSize(IrisData data, int depth) {
|
||||||
return getWorm().getMaxDistance() + fork.getMaxRange(data);
|
return getWorm().getMaxDistance() + fork.getMaxRange(data, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,16 +50,20 @@ public class IrisRavinePlacer implements IRare {
|
|||||||
@Desc("The ravine to place")
|
@Desc("The ravine to place")
|
||||||
@RegistryListResource(IrisRavine.class)
|
@RegistryListResource(IrisRavine.class)
|
||||||
private String ravine;
|
private String ravine;
|
||||||
|
@MinNumber(1)
|
||||||
|
@MaxNumber(256)
|
||||||
|
@Desc("The maximum recursion depth")
|
||||||
|
private int maxRecursion = 100;
|
||||||
|
|
||||||
public IrisRavine getRealRavine(IrisData data) {
|
public IrisRavine getRealRavine(IrisData data) {
|
||||||
return ravineCache.aquire(() -> data.getRavineLoader().load(getRavine()));
|
return ravineCache.aquire(() -> data.getRavineLoader().load(getRavine()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateRavine(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) {
|
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()) {
|
if (fail.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -80,14 +84,14 @@ public class IrisRavinePlacer implements IRare {
|
|||||||
try {
|
try {
|
||||||
int xx = x + rng.nextInt(15);
|
int xx = x + rng.nextInt(15);
|
||||||
int zz = z + 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) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail.set(true);
|
fail.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize(IrisData data) {
|
public int getSize(IrisData data, int depth) {
|
||||||
return getRealRavine(data).getMaxSize(data);
|
return getRealRavine(data).getMaxSize(data, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,9 @@ import com.volmit.iris.util.function.Consumer2;
|
|||||||
import com.volmit.iris.util.function.Consumer3;
|
import com.volmit.iris.util.function.Consumer3;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@ -373,6 +371,20 @@ public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KMap<K, V> qclear(BiConsumer<K, V> action) {
|
||||||
|
final Iterator<Map.Entry<K, V>> it = entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
final Map.Entry<K, V> entry = it.next();
|
||||||
|
it.remove();
|
||||||
|
try {
|
||||||
|
action.accept(entry.getKey(), entry.getValue());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a keypair queue
|
* Create a keypair queue
|
||||||
*
|
*
|
||||||
|
@ -87,4 +87,21 @@ public class IrisContext {
|
|||||||
public IrisComplex getComplex() {
|
public IrisComplex getComplex() {
|
||||||
return engine.getComplex();
|
return engine.getComplex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KMap<String, Object> asContext() {
|
||||||
|
var hash32 = engine.getHash32().getNow(null);
|
||||||
|
var dimension = engine.getDimension();
|
||||||
|
var mantle = engine.getMantle();
|
||||||
|
return new KMap<String, Object>()
|
||||||
|
.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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,8 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
J.aBukkit(() -> {
|
J.aBukkit(() -> {
|
||||||
if (!call(new VolmitSender(sender), args)) {
|
var volmit = new VolmitSender(sender);
|
||||||
|
if (!call(volmit, args)) {
|
||||||
|
|
||||||
if (IrisSettings.get().getGeneral().isCommandSounds()) {
|
if (IrisSettings.get().getGeneral().isCommandSounds()) {
|
||||||
if (sender instanceof Player) {
|
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 {
|
} else {
|
||||||
if (IrisSettings.get().getGeneral().isCommandSounds()) {
|
if (IrisSettings.get().getGeneral().isCommandSounds()) {
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
|
@ -376,6 +376,28 @@ public enum C {
|
|||||||
return "#" + Integer.toHexString(spin(color.awtColor(), h, s, b).getRGB()).substring(2);
|
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) {
|
public static String aura(String s, int hrad, int srad, int vrad) {
|
||||||
return aura(s, hrad, srad, vrad, 0.3D);
|
return aura(s, hrad, srad, vrad, 0.3D);
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,13 @@ import com.google.gson.JsonObject;
|
|||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.format.Form;
|
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.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -1638,4 +1642,19 @@ public class IO {
|
|||||||
int ch2 = input2.read();
|
int ch2 = input2.read();
|
||||||
return (ch2 == -1);
|
return (ch2 == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends OutputStream> void write(File file, IOFunction<FileOutputStream, T> builder, IOConsumer<T> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.RegionCoordinates;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.function.Consumer4;
|
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.math.M;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.MatterSlice;
|
import com.volmit.iris.util.matter.MatterSlice;
|
||||||
@ -84,7 +85,6 @@ public class Mantle {
|
|||||||
this.worldHeight = worldHeight;
|
this.worldHeight = worldHeight;
|
||||||
this.ioTrim = new AtomicBoolean(false);
|
this.ioTrim = new AtomicBoolean(false);
|
||||||
this.ioTectonicUnload = new AtomicBoolean(false);
|
this.ioTectonicUnload = new AtomicBoolean(false);
|
||||||
dataFolder.mkdirs();
|
|
||||||
loadedRegions = new KMap<>();
|
loadedRegions = new KMap<>();
|
||||||
lastUse = new KMap<>();
|
lastUse = new KMap<>();
|
||||||
ioBurst = MultiBurst.burst;
|
ioBurst = MultiBurst.burst;
|
||||||
@ -387,6 +387,7 @@ public class Mantle {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
loadedRegions.clear();
|
loadedRegions.clear();
|
||||||
|
IO.delete(new File(dataFolder, ".tmp"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
b.complete();
|
b.complete();
|
||||||
|
@ -27,6 +27,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.io.CountingDataInputStream;
|
import com.volmit.iris.util.io.CountingDataInputStream;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
@ -222,13 +223,8 @@ public class TectonicPlate {
|
|||||||
*/
|
*/
|
||||||
public void write(File file) throws IOException {
|
public void write(File file) throws IOException {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
File temp = File.createTempFile("iris-tectonic-plate", ".bin");
|
IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), this::write);
|
||||||
try (DataOutputStream dos = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(temp)))) {
|
|
||||||
write(dos);
|
|
||||||
}
|
|
||||||
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
|
||||||
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName() + C.RED + " in " + Form.duration(p.getMilliseconds(), 2));
|
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName() + C.RED + " in " + Form.duration(p.getMilliseconds(), 2));
|
||||||
temp.delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 !
|
|
||||||
* <p>
|
|
||||||
* You can find the project on <a href="https://github.com/MrMicky-FR/FastParticles">GitHub</a>
|
|
||||||
*
|
|
||||||
* @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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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 <T> 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<Class<?>> 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<Class<?>> obcOptionalClass(String className) {
|
|
||||||
return optionalClass(obcClassName(className));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<Class<?>> 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<Enum>) enumClass, enumName.toUpperCase());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -264,7 +264,7 @@ public class VolmitSender implements CommandSender {
|
|||||||
private Component createNoPrefixComponent(String message) {
|
private Component createNoPrefixComponent(String message) {
|
||||||
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(message));
|
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);
|
String t = C.translateAlternateColorCodes('&', message);
|
||||||
@ -273,13 +273,13 @@ public class VolmitSender implements CommandSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Component createNoPrefixComponentNoProcessing(String message) {
|
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) {
|
private Component createComponent(String message) {
|
||||||
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message));
|
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);
|
String t = C.translateAlternateColorCodes('&', getTag() + message);
|
||||||
@ -290,11 +290,11 @@ public class VolmitSender implements CommandSender {
|
|||||||
private Component createComponentRaw(String message) {
|
private Component createComponentRaw(String message) {
|
||||||
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
if (!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message));
|
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);
|
String t = C.translateAlternateColorCodes('&', getTag() + message);
|
||||||
return MiniMessage.miniMessage().deserialize(t);
|
return MiniMessage.miniMessage().deserialize(C.mini(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void showWaiting(String passive, CompletableFuture<T> f) {
|
public <T> void showWaiting(String passive, CompletableFuture<T> f) {
|
||||||
|
@ -36,7 +36,6 @@ public abstract class Looper extends Thread {
|
|||||||
//noinspection BusyWait
|
//noinspection BusyWait
|
||||||
Thread.sleep(m);
|
Thread.sleep(m);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Iris.reportError(e);
|
|
||||||
break;
|
break;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
|
@ -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> object, String name) {
|
||||||
|
return new Attachment(() -> GSON.toJson(object.call()).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KMap<String, Object> plugins() {
|
||||||
|
KMap<String, String> enabled = new KMap<>();
|
||||||
|
KMap<String, String> 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<String, Object>()
|
||||||
|
.qput("enabled", enabled)
|
||||||
|
.qput("disabled", disabled);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -25,5 +25,5 @@ libraries:
|
|||||||
commands:
|
commands:
|
||||||
iris:
|
iris:
|
||||||
aliases: [ ir, irs ]
|
aliases: [ ir, irs ]
|
||||||
api-version: '${apiversion}'
|
api-version: '${apiVersion}'
|
||||||
hotload-dependencies: false
|
hotload-dependencies: false
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
41
gradlew
vendored
41
gradlew
vendored
@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (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.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@ -80,13 +80,11 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@ -133,22 +131,29 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
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
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
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 ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | 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" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# 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 -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
@ -205,6 +214,12 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
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.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
35
gradlew.bat
vendored
35
gradlew.bat
vendored
@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@ -25,7 +25,8 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
@ -23,19 +23,19 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
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(
|
include(
|
||||||
':nms:v1_21_R4',
|
":nms:v1_21_R4",
|
||||||
':nms:v1_21_R3',
|
":nms:v1_21_R3",
|
||||||
':nms:v1_21_R2',
|
":nms:v1_21_R2",
|
||||||
':nms:v1_21_R1',
|
":nms:v1_21_R1",
|
||||||
':nms:v1_20_R4',
|
":nms:v1_20_R4",
|
||||||
':nms:v1_20_R3',
|
":nms:v1_20_R3",
|
||||||
':nms:v1_20_R2',
|
":nms:v1_20_R2",
|
||||||
':nms:v1_20_R1',
|
":nms:v1_20_R1",
|
||||||
)
|
)
|
Loading…
x
Reference in New Issue
Block a user