mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-21 16:09:29 +00:00
Compare commits
131 Commits
old/iris4
...
feat/exclu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf41364da7 | ||
|
|
f6033d9c1b | ||
|
|
f42bf07d4e | ||
|
|
289813b044 | ||
|
|
b209f69bba | ||
|
|
790fde02a8 | ||
|
|
eddc0c81f2 | ||
|
|
d8c3fd8e6c | ||
|
|
984d294bab | ||
|
|
96b0db309a | ||
|
|
b5da0dd33f | ||
|
|
1ac482ff49 | ||
|
|
fb0bc112e3 | ||
|
|
407e51378c | ||
|
|
c468eb1ab1 | ||
|
|
bdb7cc61e5 | ||
|
|
e8f9e841c4 | ||
|
|
1b1b9d97b7 | ||
|
|
24355064ff | ||
|
|
06a45056d9 | ||
|
|
dfe4894be7 | ||
|
|
8eb2287ec0 | ||
|
|
c4f0722614 | ||
|
|
7fa1484b21 | ||
|
|
1c5eb8b910 | ||
|
|
94bf530d93 | ||
|
|
686ae57b5b | ||
|
|
a911685aaf | ||
|
|
6899761ca9 | ||
|
|
a58958fd62 | ||
|
|
307f3c9158 | ||
|
|
4f275c2e06 | ||
|
|
7e4e3f3cd8 | ||
|
|
84e5add564 | ||
|
|
4d4adbb76f | ||
|
|
ff2f285784 | ||
|
|
8b1636e78a | ||
|
|
3bdad10562 | ||
|
|
ac03a977aa | ||
|
|
d7270f66e1 | ||
|
|
b220b1bffa | ||
|
|
4796fe98cb | ||
|
|
ece905ec6e | ||
|
|
53c9e7c04c | ||
|
|
29f6f52443 | ||
|
|
a778cc51a6 | ||
|
|
c6963d0cd3 | ||
|
|
489844f61b | ||
|
|
4d1b0246ca | ||
|
|
13f3511fa8 | ||
|
|
f6f2766315 | ||
|
|
56530a1245 | ||
|
|
210a1f29a7 | ||
|
|
847bf972ae | ||
|
|
e5d21fdf7e | ||
|
|
0b2fd3b358 | ||
|
|
10484d1226 | ||
|
|
ce0092c52a | ||
|
|
474e033c2b | ||
|
|
62aad1f497 | ||
|
|
32b5157682 | ||
|
|
70717ea282 | ||
|
|
15975f108c | ||
|
|
66c66e82c1 | ||
|
|
4f6da95d8e | ||
|
|
b37ccbdf01 | ||
|
|
30dbe0881a | ||
|
|
20ad4657a9 | ||
|
|
d4986f42a6 | ||
|
|
8df15c0c2d | ||
|
|
24e1c578c8 | ||
|
|
1c3bff7559 | ||
|
|
a09657b4d0 | ||
|
|
910220d3ca | ||
|
|
fc05c24e3a | ||
|
|
e1a7e772cf | ||
|
|
3c6411c322 | ||
|
|
628761affa | ||
|
|
fa7b0f68ff | ||
|
|
487d0ac237 | ||
|
|
e79e3fbe45 | ||
|
|
23a0ab23aa | ||
|
|
c78ffab948 | ||
|
|
d58f497b71 | ||
|
|
3284ab84c5 | ||
|
|
5cf0ac9315 | ||
|
|
4e4e820826 | ||
|
|
cb6e4570f4 | ||
|
|
fb59c7370d | ||
|
|
c16e65f0a8 | ||
|
|
d9681edf62 | ||
|
|
520c156d5f | ||
|
|
5c26ec2521 | ||
|
|
d192e2b6d1 | ||
|
|
5b60b655ed | ||
|
|
97c7ac0528 | ||
|
|
090ff730a7 | ||
|
|
c1f797e7c9 | ||
|
|
4a1a6b80a6 | ||
|
|
e189b2389c | ||
|
|
3265447536 | ||
|
|
8c7c9f89e1 | ||
|
|
d7a991b9b3 | ||
|
|
abf6c93f2e | ||
|
|
1b76a66760 | ||
|
|
c83ac67b47 | ||
|
|
1dca502a90 | ||
|
|
cacef8c8fc | ||
|
|
623fd45ef4 | ||
|
|
007b4b0b53 | ||
|
|
b6bacee095 | ||
|
|
d5251350a1 | ||
|
|
1f9c72d093 | ||
|
|
a1495a10e5 | ||
|
|
11ae48bea1 | ||
|
|
b0f4b29a2d | ||
|
|
c38bb1cd01 | ||
|
|
7faa727bd2 | ||
|
|
9e40259ca2 | ||
|
|
94a7692735 | ||
|
|
8b803a87f0 | ||
|
|
3ae6e92eaf | ||
|
|
0f3c52a5aa | ||
|
|
747be7aa09 | ||
|
|
d651f204f8 | ||
|
|
2bd3ac7a9b | ||
|
|
5e437b34e3 | ||
|
|
a5ef89a128 | ||
|
|
558b8e4eca | ||
|
|
0a001b8a63 | ||
|
|
6c6c9654c1 |
@@ -15,17 +15,17 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
|
|
||||||
### Command Line Builds
|
### Command Line Builds
|
||||||
|
|
||||||
1. Install [Java JDK 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
1. Install [Java JDK 21](https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html)
|
||||||
2. Set the JDK installation path to `JAVA_HOME` as an environment variable.
|
2. Set the JDK installation path to `JAVA_HOME` as an environment variable.
|
||||||
* Windows
|
* Windows
|
||||||
1. Start > Type `env` and press Enter
|
1. Start > Type `env` and press Enter
|
||||||
2. Advanced > Environment Variables
|
2. Advanced > Environment Variables
|
||||||
3. Under System Variables, click `New...`
|
3. Under System Variables, click `New...`
|
||||||
4. Variable Name: `JAVA_HOME`
|
4. Variable Name: `JAVA_HOME`
|
||||||
5. Variable Value: `C:\Program Files\Java\jdk-17.0.1` (verify this exists after installing java don't just copy
|
5. Variable Value: `C:\Program Files\Java\jdk-21.0.1` (verify this exists after installing java don't just copy
|
||||||
the example text)
|
the example text)
|
||||||
* MacOS
|
* MacOS
|
||||||
1. Run `/usr/libexec/java_home -V` and look for Java 17
|
1. Run `/usr/libexec/java_home -V` and look for Java 21
|
||||||
2. Run `sudo nano ~/.zshenv`
|
2. Run `sudo nano ~/.zshenv`
|
||||||
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
||||||
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
||||||
@@ -35,7 +35,7 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
|
|
||||||
### IDE Builds (for development)
|
### IDE Builds (for development)
|
||||||
|
|
||||||
* Configure ITJ Gradle to use JDK 17 (in settings, search for gradle)
|
* Configure ITJ Gradle to use JDK 21 (in settings, search for gradle)
|
||||||
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
||||||
prefer.
|
prefer.
|
||||||
* Resync the project & run your newly created task (under the development folder in gradle tasks!)
|
* Resync the project & run your newly created task (under the development folder in gradle tasks!)
|
||||||
|
|||||||
94
build.gradle
94
build.gradle
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -32,7 +32,8 @@ plugins {
|
|||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
version '4.0-1.19.2-1.21.1'
|
|
||||||
|
version '3.6.5-1.20.1-1.21.4'
|
||||||
|
|
||||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||||
// ======================== WINDOWS =============================
|
// ======================== WINDOWS =============================
|
||||||
@@ -43,7 +44,8 @@ registerCustomOutputTask('Coco', 'D://mcsm/plugins')
|
|||||||
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
||||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
||||||
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
||||||
registerCustomOutputTask('Pixel', 'D://Iris Dimension Engine/1.20.4 - Development/plugins')
|
registerCustomOutputTask('PixelFury', 'C://Users/repix/workplace/Iris/1.21.3 - Development-Public-v3/plugins')
|
||||||
|
registerCustomOutputTask('PixelFuryDev', 'C://Users/repix/workplace/Iris/1.21.4 - Development-v3/plugins')
|
||||||
// ========================== UNIX ==============================
|
// ========================== UNIX ==============================
|
||||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||||
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
||||||
@@ -52,27 +54,22 @@ registerCustomOutputTaskUnix('CrazyDev22LT', '/home/julian/Desktop/server/plugin
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
def NMS_BINDINGS = Map.of(
|
def NMS_BINDINGS = Map.of(
|
||||||
"v1_21_R1", "1.21-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_R4", "1.20.6-R0.1-SNAPSHOT",
|
||||||
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
||||||
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
||||||
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
||||||
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
|
||||||
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
|
||||||
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
|
||||||
)
|
)
|
||||||
def JVM_VERSION = Map.of(
|
def JVM_VERSION = Map.of()
|
||||||
"v1_21_R1", 21,
|
|
||||||
"v1_20_R4", 21,
|
|
||||||
)
|
|
||||||
def entryPoint = 'com.volmit.iris.server.EntryPoint'
|
|
||||||
NMS_BINDINGS.each { nms ->
|
NMS_BINDINGS.each { nms ->
|
||||||
project(":nms:${nms.key}") {
|
project(":nms:${nms.key}") {
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'com.volmit.nmstools'
|
apply plugin: 'com.volmit.nmstools'
|
||||||
|
|
||||||
nmsTools {
|
nmsTools {
|
||||||
it.jvm = JVM_VERSION.getOrDefault(nms.key, 17)
|
it.jvm = JVM_VERSION.getOrDefault(nms.key, 21)
|
||||||
it.version = nms.value
|
it.version = nms.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,18 +84,14 @@ shadowJar {
|
|||||||
dependsOn(":nms:${it.key}:remap")
|
dependsOn(":nms:${it.key}:remap")
|
||||||
from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}-mapped.jar")
|
from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}-mapped.jar")
|
||||||
}
|
}
|
||||||
//dependsOn(':com.volmit.gui:build')
|
|
||||||
|
|
||||||
//minimize()
|
//minimize()
|
||||||
append("plugin.yml")
|
append("plugin.yml")
|
||||||
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
||||||
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
||||||
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
||||||
|
relocate 'org.bstats', 'com.volmit.util.metrics'
|
||||||
archiveFileName.set("Iris-${project.version}.jar")
|
archiveFileName.set("Iris-${project.version}.jar")
|
||||||
|
|
||||||
manifest {
|
|
||||||
attributes 'Main-Class': entryPoint
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -115,34 +108,36 @@ allprojects {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url "https://repo.papermc.io/repository/maven-public/"}
|
maven { url "https://repo.papermc.io/repository/maven-public/" }
|
||||||
maven { url "https://repo.codemc.org/repository/maven-public" }
|
maven { url "https://repo.codemc.org/repository/maven-public" }
|
||||||
maven { url "https://mvn.lumine.io/repository/maven-public/" }
|
maven { url "https://mvn.lumine.io/repository/maven-public/" }
|
||||||
maven { url "https://jitpack.io"}
|
maven { url "https://jitpack.io" }
|
||||||
|
|
||||||
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
|
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
|
||||||
maven { url "https://mvn.lumine.io/repository/maven/" }
|
maven { url "https://mvn.lumine.io/repository/maven/" }
|
||||||
maven { url "https://repo.triumphteam.dev/snapshots" }
|
maven { url "https://repo.triumphteam.dev/snapshots" }
|
||||||
maven { url "https://repo.mineinabyss.com/releases" }
|
maven { url "https://repo.mineinabyss.com/releases" }
|
||||||
maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
|
maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
|
||||||
maven { url "https://repo.oraxen.com/releases" }
|
maven { url "https://repo.nexomc.com/snapshots/" }
|
||||||
|
maven { url "https://libraries.minecraft.net" }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Provided or Classpath
|
// Provided or Classpath
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.34'
|
compileOnly 'org.projectlombok:lombok:1.18.36'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
annotationProcessor 'org.projectlombok:lombok:1.18.36'
|
||||||
|
|
||||||
// Shaded
|
// Shaded
|
||||||
implementation 'com.dfsek:Paralithic:0.4.0'
|
implementation 'com.dfsek:paralithic:0.8.1'
|
||||||
implementation 'io.papermc:paperlib:1.0.5'
|
implementation 'io.papermc:paperlib:1.0.5'
|
||||||
implementation "net.kyori:adventure-text-minimessage:4.17.0"
|
implementation "net.kyori:adventure-text-minimessage:4.17.0"
|
||||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
|
implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
|
||||||
implementation 'net.kyori:adventure-api:4.17.0'
|
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:javacpp:1.5.10'
|
||||||
//implementation 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
|
//implementation 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
|
||||||
//implementation "org.deeplearning4j:deeplearning4j-core:1.0.0-M2.1"
|
|
||||||
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
||||||
|
compileOnly 'io.lumine:MythicCrucible-Dist:2.0.0'
|
||||||
|
|
||||||
// Dynamically Loaded
|
// Dynamically Loaded
|
||||||
compileOnly 'io.timeandspace:smoothie-map:2.0.2'
|
compileOnly 'io.timeandspace:smoothie-map:2.0.2'
|
||||||
@@ -156,11 +151,7 @@ allprojects {
|
|||||||
compileOnly 'rhino:js:1.7R2'
|
compileOnly 'rhino:js:1.7R2'
|
||||||
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
||||||
compileOnly 'org.apache.commons:commons-lang3:3.12.0'
|
compileOnly 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
compileOnly 'net.bytebuddy:byte-buddy:1.14.14'
|
compileOnly 'com.github.oshi:oshi-core:6.6.5'
|
||||||
compileOnly 'net.bytebuddy:byte-buddy-agent:1.12.8'
|
|
||||||
compileOnly 'org.bytedeco:javacpp:1.5.10'
|
|
||||||
compileOnly 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
|
|
||||||
compileOnly 'io.netty:netty-all:4.1.112.Final'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,20 +161,35 @@ allprojects {
|
|||||||
options.compilerArgs << '-parameters'
|
options.compilerArgs << '-parameters'
|
||||||
options.encoding = "UTF-8"
|
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() != "17") {
|
if (JavaVersion.current().toString() != "21") {
|
||||||
System.err.println()
|
System.err.println()
|
||||||
System.err.println("=========================================================================================================")
|
System.err.println("=========================================================================================================")
|
||||||
System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current())
|
System.err.println("You must run gradle on Java 21. You are using " + JavaVersion.current())
|
||||||
System.err.println()
|
System.err.println()
|
||||||
System.err.println("=== For IDEs ===")
|
System.err.println("=== For IDEs ===")
|
||||||
System.err.println("1. Configure the project for Java 17")
|
System.err.println("1. Configure the project for Java 21")
|
||||||
System.err.println("2. Configure the bundled gradle to use Java 17 in settings")
|
System.err.println("2. Configure the bundled gradle to use Java 21 in settings")
|
||||||
System.err.println()
|
System.err.println()
|
||||||
System.err.println("=== For Command Line (gradlew) ===")
|
System.err.println("=== For Command Line (gradlew) ===")
|
||||||
System.err.println("1. Install JDK 17 from https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html")
|
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-17.0.1")
|
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("3. Open a new command prompt window to get the new environment variables if need be.")
|
||||||
System.err.println("=========================================================================================================")
|
System.err.println("=========================================================================================================")
|
||||||
System.err.println()
|
System.err.println()
|
||||||
@@ -197,6 +203,20 @@ task iris(type: Copy) {
|
|||||||
dependsOn(build)
|
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) {
|
def registerCustomOutputTask(name, path) {
|
||||||
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,7 +34,7 @@ compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/' }
|
maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'}
|
||||||
maven { url 'https://repo.auxilor.io/repository/maven-public/' }
|
maven { url 'https://repo.auxilor.io/repository/maven-public/' }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ dependencies {
|
|||||||
|
|
||||||
// Third Party Integrations
|
// Third Party Integrations
|
||||||
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
||||||
compileOnly 'io.th0rgal:oraxen:1.173.0'
|
compileOnly 'com.nexomc:nexo:1.0.0-dev.38'
|
||||||
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
||||||
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
||||||
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
||||||
@@ -71,6 +71,9 @@ dependencies {
|
|||||||
//implementation files('libs/CustomItems.jar')
|
//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.
|
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,19 +30,19 @@ import com.volmit.iris.core.loader.IrisData;
|
|||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
|
||||||
import com.volmit.iris.core.safeguard.UtilsSFG;
|
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.core.tools.IrisWorldCreator;
|
||||||
import com.volmit.iris.engine.EnginePanic;
|
import com.volmit.iris.engine.EnginePanic;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.engine.object.IrisCompat;
|
import com.volmit.iris.engine.object.IrisCompat;
|
||||||
|
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
import com.volmit.iris.engine.object.IrisWorld;
|
import com.volmit.iris.engine.object.IrisWorld;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
||||||
import com.volmit.iris.server.master.IrisMasterServer;
|
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
||||||
import com.volmit.iris.server.node.IrisServer;
|
import com.volmit.iris.core.safeguard.UtilsSFG;
|
||||||
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.exceptions.IrisException;
|
import com.volmit.iris.util.exceptions.IrisException;
|
||||||
@@ -58,7 +58,6 @@ import com.volmit.iris.util.math.RNG;
|
|||||||
import com.volmit.iris.util.misc.getHardware;
|
import com.volmit.iris.util.misc.getHardware;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.Metrics;
|
|
||||||
import com.volmit.iris.util.plugin.VolmitPlugin;
|
import com.volmit.iris.util.plugin.VolmitPlugin;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.reflect.ShadeFix;
|
import com.volmit.iris.util.reflect.ShadeFix;
|
||||||
@@ -66,12 +65,12 @@ 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 io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.bytebuddy.agent.ByteBuddyAgent;
|
|
||||||
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;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
import org.bstats.charts.DrilldownPie;
|
||||||
import org.apache.commons.io.filefilter.TrueFileFilter;
|
import org.bstats.charts.SimplePie;
|
||||||
|
import org.bstats.charts.SingleLineChart;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
@@ -80,29 +79,30 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.*;
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.generator.BiomeProvider;
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.plugin.IllegalPluginAccessException;
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.InitializeSafeguard;
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||||
|
import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware;
|
||||||
|
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
public class Iris extends VolmitPlugin implements Listener {
|
public class Iris extends VolmitPlugin implements Listener {
|
||||||
public static final String OVERWORLD_TAG = "3800";
|
|
||||||
|
|
||||||
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
||||||
|
|
||||||
public static Iris instance;
|
public static Iris instance;
|
||||||
@@ -111,7 +111,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
public static MythicMobsLink linkMythicMobs;
|
public static MythicMobsLink linkMythicMobs;
|
||||||
public static IrisCompat compat;
|
public static IrisCompat compat;
|
||||||
public static FileWatcher configWatcher;
|
public static FileWatcher configWatcher;
|
||||||
private static IrisServer server;
|
|
||||||
private static VolmitSender sender;
|
private static VolmitSender sender;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -323,7 +322,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
public static void info(String format, Object... args) {
|
public static void info(String format, Object... args) {
|
||||||
msg(C.WHITE + String.format(format, args));
|
msg(C.WHITE + String.format(format, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void safeguard(String format, Object... args) {
|
public static void safeguard(String format, Object... args) {
|
||||||
msg(C.RESET + String.format(format, args));
|
msg(C.RESET + String.format(format, args));
|
||||||
}
|
}
|
||||||
@@ -394,25 +392,27 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void reportError(Throwable e) {
|
public static void reportError(Throwable e) {
|
||||||
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
if (IrisSettings.get().getGeneral().isDebug()) {
|
||||||
|
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
||||||
|
|
||||||
if (e.getCause() != null) {
|
if (e.getCause() != null) {
|
||||||
n += "-" + e.getCause().getStackTrace()[0].getClassName() + "-" + e.getCause().getStackTrace()[0].getLineNumber();
|
n += "-" + e.getCause().getStackTrace()[0].getClassName() + "-" + e.getCause().getStackTrace()[0].getLineNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = instance.getDataFile("debug", "caught-exceptions", n + ".txt");
|
||||||
|
|
||||||
|
if (!f.exists()) {
|
||||||
|
J.attempt(() -> {
|
||||||
|
PrintWriter pw = new PrintWriter(f);
|
||||||
|
pw.println("Thread: " + Thread.currentThread().getName());
|
||||||
|
pw.println("First: " + new Date(M.ms()));
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
pw.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.debug("Exception Logged: " + e.getClass().getSimpleName() + ": " + C.RESET + "" + C.LIGHT_PURPLE + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
File f = instance.getDataFile("debug", "caught-exceptions", n + ".txt");
|
|
||||||
|
|
||||||
if (!f.exists()) {
|
|
||||||
J.attempt(() -> {
|
|
||||||
PrintWriter pw = new PrintWriter(f);
|
|
||||||
pw.println("Thread: " + Thread.currentThread().getName());
|
|
||||||
pw.println("First: " + new Date(M.ms()));
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
pw.close();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.debug("Exception Logged: " + e.getClass().getSimpleName() + ": " + C.RESET + "" + C.LIGHT_PURPLE + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dump() {
|
public static void dump() {
|
||||||
@@ -452,73 +452,41 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
private static void fixShading() {
|
private static void fixShading() {
|
||||||
ShadeFix.fix(ComponentSerializer.class);
|
ShadeFix.fix(ComponentSerializer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enable() {
|
private void enable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
InitializeSafeguard();
|
|
||||||
ByteBuddyAgent.install();
|
|
||||||
services = new KMap<>();
|
services = new KMap<>();
|
||||||
setupAudience();
|
setupAudience();
|
||||||
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));
|
||||||
INMS.get();
|
INMS.get();
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
IrisSafeguard.instance.IrisSafeguardSystem();
|
|
||||||
getSender().setTag(getTag());
|
|
||||||
INMS.get().injectBukkit();
|
|
||||||
if (IrisSafeguard.instance.unstablemode && !IrisSafeguard.instance.acceptUnstable)
|
|
||||||
IrisSafeguard.instance.earlySplash();
|
|
||||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||||
|
ServerConfigurator.configure();
|
||||||
|
new IrisContextInjector();
|
||||||
|
IrisSafeguard.IrisSafeguardSystem();
|
||||||
|
getSender().setTag(getTag());
|
||||||
|
IrisSafeguard.earlySplash();
|
||||||
linkMultiverseCore = new MultiverseCoreLink();
|
linkMultiverseCore = new MultiverseCoreLink();
|
||||||
linkMythicMobs = new MythicMobsLink();
|
linkMythicMobs = new MythicMobsLink();
|
||||||
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
||||||
services.values().forEach(IrisService::onEnable);
|
services.values().forEach(IrisService::onEnable);
|
||||||
services.values().forEach(this::registerListener);
|
services.values().forEach(this::registerListener);
|
||||||
ServerConfigurator.setupDataPack();
|
J.s(() -> {
|
||||||
installMainDimension();
|
J.a(() -> PaperLib.suggestPaper(this));
|
||||||
try {
|
J.a(() -> IO.delete(getTemp()));
|
||||||
info("Starting server...");
|
J.a(LazyPregenerator::loadLazyGenerators, 100);
|
||||||
try {
|
J.a(this::bstats);
|
||||||
int port = Integer.parseInt(System.getProperty("com.volmit.iris.server.port"));
|
J.ar(this::checkConfigHotload, 60);
|
||||||
String[] remote = Optional.ofNullable(System.getProperty("com.volmit.iris.server.remote"))
|
J.sr(this::tickQueue, 0);
|
||||||
.map(String::trim)
|
J.s(this::setupPapi);
|
||||||
.map(s -> s.isBlank() ? null : s.split(","))
|
J.a(ServerConfigurator::configure, 20);
|
||||||
.orElse(new String[0]);
|
splash();
|
||||||
server = remote.length > 0 ? new IrisMasterServer(port, remote) : new IrisServer(port);
|
UtilsSFG.splash();
|
||||||
} catch (NullPointerException | NumberFormatException ignored) {
|
|
||||||
var serverSettings = IrisSettings.get().getServer();
|
|
||||||
if (serverSettings.isActive()) {
|
|
||||||
server = serverSettings.isRemote() ?
|
|
||||||
new IrisMasterServer(serverSettings.getPort(), serverSettings.remote) :
|
|
||||||
new IrisServer(serverSettings.getPort());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
} catch (Throwable e) {
|
|
||||||
error("Failed to start server: " + e.getClass().getSimpleName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IrisSafeguard.instance.acceptUnstable && IrisSafeguard.instance.unstablemode) {
|
autoStartStudio();
|
||||||
Iris.info(C.RED + "World loading has been disabled until the incompatibility is resolved.");
|
checkForBukkitWorlds();
|
||||||
Iris.info(C.DARK_RED + "Alternatively, go to plugins/iris/settings.json and set ignoreBootMode to true.");
|
IrisToolbelt.retainMantleDataForSlice(String.class.getCanonicalName());
|
||||||
} else {
|
IrisToolbelt.retainMantleDataForSlice(BlockData.class.getCanonicalName());
|
||||||
J.s(() -> {
|
});
|
||||||
J.a(() -> PaperLib.suggestPaper(this));
|
|
||||||
J.a(() -> IO.delete(getTemp()));
|
|
||||||
J.a(LazyPregenerator::loadLazyGenerators, 100);
|
|
||||||
J.a(this::bstats);
|
|
||||||
J.ar(this::checkConfigHotload, 60);
|
|
||||||
J.sr(this::tickQueue, 0);
|
|
||||||
J.s(this::setupPapi);
|
|
||||||
J.a(ServerConfigurator::configure, 20);
|
|
||||||
splash();
|
|
||||||
UtilsSFG.splash();
|
|
||||||
autoStartStudio();
|
|
||||||
checkForBukkitWorlds();
|
|
||||||
IrisToolbelt.retainMantleDataForSlice(String.class.getCanonicalName());
|
|
||||||
IrisToolbelt.retainMantleDataForSlice(BlockData.class.getCanonicalName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForBukkitWorlds() {
|
private void checkForBukkitWorlds() {
|
||||||
@@ -531,60 +499,31 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (String s : section.getKeys(false)) {
|
for (String s : section.getKeys(false)) {
|
||||||
try {
|
ConfigurationSection entry = section.getConfigurationSection(s);
|
||||||
|
if (!entry.contains("generator", true)) {
|
||||||
ConfigurationSection entry = section.getConfigurationSection(s);
|
continue;
|
||||||
if (!entry.contains("backup-generator", true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String generator = entry.getString("backup-generator");
|
|
||||||
if (!generator.startsWith("Iris")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new File(Bukkit.getWorldContainer().getPath() + "/" + s).exists()) {
|
|
||||||
File world = new File(Bukkit.getWorldContainer().getPath() + "/" + s + "/iris/engine-data/");
|
|
||||||
IOFileFilter jsonFilter = org.apache.commons.io.filefilter.FileFilterUtils.suffixFileFilter(".json");
|
|
||||||
Collection<File> files = FileUtils.listFiles(world, jsonFilter, TrueFileFilter.INSTANCE);
|
|
||||||
if (files.size() != 1) {
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
Iris.info(C.RED + "Failed to load " + C.GRAY + s + C.RED + ". No valid engine-data file was found.");
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : files) {
|
|
||||||
int lastDotIndex = file.getName().lastIndexOf(".");
|
|
||||||
generator = file.getName().substring(0, lastDotIndex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (generator.startsWith("Iris:")) {
|
|
||||||
generator = generator.split("\\Q:\\E")[1];
|
|
||||||
} else if (generator.equalsIgnoreCase("Iris")) {
|
|
||||||
generator = IrisSettings.get().getGenerator().getDefaultWorldType();
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info("2 World: %s | Generator: %s", s, generator);
|
|
||||||
|
|
||||||
if (Bukkit.getWorlds().stream().anyMatch(w -> w.getName().equals(s))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
|
||||||
new WorldCreator(s)
|
|
||||||
.generator(getDefaultWorldGenerator(s, generator))
|
|
||||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
|
||||||
.createWorld();
|
|
||||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
|
||||||
} catch (Exception e) {
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
Iris.info(C.RED + "Failed to load " + C.GRAY + s);
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String generator = entry.getString("generator");
|
||||||
|
if (generator.startsWith("Iris:")) {
|
||||||
|
generator = generator.split("\\Q:\\E")[1];
|
||||||
|
} else if (generator.equalsIgnoreCase("Iris")) {
|
||||||
|
generator = IrisSettings.get().getGenerator().getDefaultWorldType();
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Bukkit.getWorld(s) != null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Iris.info("Loading World: %s | Generator: %s", s, generator);
|
||||||
|
|
||||||
|
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||||
|
WorldCreator c = new WorldCreator(s)
|
||||||
|
.generator(getDefaultWorldGenerator(s, generator))
|
||||||
|
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
|
||||||
|
INMS.get().createWorld(c);
|
||||||
|
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -633,12 +572,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
Bukkit.getWorlds().stream()
|
|
||||||
.filter(IrisToolbelt::isIrisWorld)
|
|
||||||
.forEach(w -> {
|
|
||||||
Engine engine = IrisToolbelt.access(w).getEngine();
|
|
||||||
engine.close();
|
|
||||||
});
|
|
||||||
services.values().forEach(IrisService::onDisable);
|
services.values().forEach(IrisService::onDisable);
|
||||||
Bukkit.getScheduler().cancelTasks(this);
|
Bukkit.getScheduler().cancelTasks(this);
|
||||||
HandlerList.unregisterAll((Plugin) this);
|
HandlerList.unregisterAll((Plugin) this);
|
||||||
@@ -666,10 +599,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTag(String subTag) {
|
public String getTag(String subTag) {
|
||||||
if (IrisSafeguard.instance.unstablemode) {
|
if (unstablemode) {
|
||||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.RED + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.RED + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
}
|
}
|
||||||
if (IrisSafeguard.instance.warningmode) {
|
if (warningmode) {
|
||||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GOLD + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GOLD + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
}
|
}
|
||||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
@@ -678,7 +611,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
private boolean setupChecks() {
|
private boolean setupChecks() {
|
||||||
boolean passed = true;
|
boolean passed = true;
|
||||||
Iris.info("Server type & version: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion());
|
Iris.info("Version Information: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion());
|
||||||
if (INMS.get() instanceof NMSBinding1X) {
|
if (INMS.get() instanceof NMSBinding1X) {
|
||||||
passed = false;
|
passed = false;
|
||||||
Iris.warn("============================================");
|
Iris.warn("============================================");
|
||||||
@@ -731,7 +664,50 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
private void bstats() {
|
private void bstats() {
|
||||||
if (IrisSettings.get().getGeneral().isPluginMetrics()) {
|
if (IrisSettings.get().getGeneral().isPluginMetrics()) {
|
||||||
J.s(() -> new Metrics(Iris.instance, 8757));
|
J.s(() -> {
|
||||||
|
var metrics = new Metrics(Iris.instance, 24220);
|
||||||
|
metrics.addCustomChart(new SingleLineChart("custom_dimensions", () -> Bukkit.getWorlds()
|
||||||
|
.stream()
|
||||||
|
.filter(IrisToolbelt::isIrisWorld)
|
||||||
|
.mapToInt(w -> 1)
|
||||||
|
.sum()));
|
||||||
|
|
||||||
|
metrics.addCustomChart(new DrilldownPie("used_packs", () -> Bukkit.getWorlds().stream()
|
||||||
|
.map(IrisToolbelt::access)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(PlatformChunkGenerator::getEngine)
|
||||||
|
.collect(Collectors.toMap(engine -> engine.getDimension().getLoadKey(), engine -> {
|
||||||
|
var hash32 = engine.getHash32().getNow(null);
|
||||||
|
if (hash32 == null) return Map.of();
|
||||||
|
int version = engine.getDimension().getVersion();
|
||||||
|
String checksum = Long.toHexString(hash32);
|
||||||
|
|
||||||
|
return Map.of("v" + version + " (" + checksum + ")", 1);
|
||||||
|
}, (a, b) -> {
|
||||||
|
Map<String, Integer> merged = new HashMap<>(a);
|
||||||
|
b.forEach((k, v) -> merged.merge(k, v, Integer::sum));
|
||||||
|
return merged;
|
||||||
|
}))));
|
||||||
|
|
||||||
|
|
||||||
|
var info = new SystemInfo().getHardware();
|
||||||
|
var cpu = info.getProcessor().getProcessorIdentifier();
|
||||||
|
var mem = info.getMemory();
|
||||||
|
metrics.addCustomChart(new SimplePie("cpu_model", cpu::getName));
|
||||||
|
|
||||||
|
var nf = NumberFormat.getInstance(Locale.ENGLISH);
|
||||||
|
nf.setMinimumFractionDigits(0);
|
||||||
|
nf.setMaximumFractionDigits(2);
|
||||||
|
nf.setRoundingMode(RoundingMode.HALF_UP);
|
||||||
|
|
||||||
|
metrics.addCustomChart(new DrilldownPie("memory", () -> {
|
||||||
|
double total = mem.getTotal() * 1E-9;
|
||||||
|
double alloc = Math.min(total, Runtime.getRuntime().maxMemory() * 1E-9);
|
||||||
|
return Map.of(nf.format(alloc), Map.of(nf.format(total), 1));
|
||||||
|
}));
|
||||||
|
|
||||||
|
postShutdown.add(metrics::shutdown);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,48 +720,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
s.sendMessage(C.IRIS + "[" + C.DARK_GRAY + "Iris" + C.IRIS + "]" + C.GRAY + ": " + msg);
|
s.sendMessage(C.IRIS + "[" + C.DARK_GRAY + "Iris" + C.IRIS + "]" + C.GRAY + ": " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installMainDimension() {
|
|
||||||
try {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.load(new FileInputStream("server.properties"));
|
|
||||||
String world = props.getProperty("level-name");
|
|
||||||
if (world == null) return;
|
|
||||||
|
|
||||||
FileConfiguration fc = new YamlConfiguration();
|
|
||||||
fc.load(new File("bukkit.yml"));
|
|
||||||
String id = fc.getString("worlds." + world + ".generator");
|
|
||||||
if (id.startsWith("Iris:")) {
|
|
||||||
id = id.split("\\Q:\\E")[1];
|
|
||||||
} else if (id.equalsIgnoreCase("Iris")) {
|
|
||||||
id = IrisSettings.get().getGenerator().getDefaultWorldType();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisDimension dim;
|
|
||||||
if (id == null || id.isEmpty()) {
|
|
||||||
dim = IrisData.loadAnyDimension(IrisSettings.get().getGenerator().getDefaultWorldType());
|
|
||||||
} else {
|
|
||||||
dim = IrisData.loadAnyDimension(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
File w = new File(Bukkit.getWorldContainer(), world);
|
|
||||||
File packFolder = new File(w, "/iris/pack");
|
|
||||||
if (!packFolder.exists() || packFolder.listFiles().length == 0) {
|
|
||||||
packFolder.mkdirs();
|
|
||||||
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w);
|
|
||||||
}
|
|
||||||
if (packFolder.exists()) {
|
|
||||||
IrisDimension worldDim = IrisData.get(packFolder).getDimensionLoader().load(id);
|
|
||||||
if (worldDim != null) dim = worldDim;
|
|
||||||
}
|
|
||||||
|
|
||||||
INMS.get().registerDimension("overworld", dim);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) {
|
public BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) {
|
||||||
@@ -828,11 +762,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
Iris.info("Resolved missing dimension, proceeding with generation.");
|
Iris.info("Resolved missing dimension, proceeding with generation.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File packFolder = new File(Bukkit.getWorldContainer(), worldName + "/iris/pack");
|
|
||||||
if (packFolder.exists()) {
|
|
||||||
IrisDimension worldDim = IrisData.get(packFolder).getDimensionLoader().load(id);
|
|
||||||
if (worldDim != null) dim = worldDim;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.debug("Assuming IrisDimension: " + dim.getName());
|
Iris.debug("Assuming IrisDimension: " + dim.getName());
|
||||||
|
|
||||||
@@ -852,10 +781,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
ff.mkdirs();
|
ff.mkdirs();
|
||||||
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder());
|
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder());
|
||||||
}
|
}
|
||||||
if (!INMS.get().registerDimension(worldName, dim)) {
|
|
||||||
throw new IllegalStateException("Unable to register dimension " + dim.getName());
|
|
||||||
}
|
|
||||||
INMS.get().reconnectAll();
|
|
||||||
|
|
||||||
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
||||||
}
|
}
|
||||||
@@ -867,52 +792,71 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
String padd = Form.repeat(" ", 8);
|
String padd = Form.repeat(" ", 8);
|
||||||
String padd2 = Form.repeat(" ", 4);
|
String padd2 = Form.repeat(" ", 4);
|
||||||
|
String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "<rainbow>Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion()};
|
||||||
String colorIris, colorVolmit, colorVersion;
|
if (unstablemode) {
|
||||||
if (IrisSafeguard.instance.unstablemode) {
|
info = new String[]{"", "", "", "", "", padd2 + C.RED + " Iris", padd2 + C.GRAY + " by " + C.DARK_RED + "Volmit Software", padd2 + C.GRAY + " v" + C.RED + getDescription().getVersion()};
|
||||||
colorIris = String.valueOf(C.RED);
|
}
|
||||||
colorVolmit = String.valueOf(C.DARK_RED);
|
if (warningmode) {
|
||||||
colorVersion = String.valueOf(C.RED);
|
info = new String[]{"", "", "", "", "", padd2 + C.GOLD + " Iris", padd2 + C.GRAY + " by " + C.GOLD + "Volmit Software", padd2 + C.GRAY + " v" + C.GOLD + getDescription().getVersion()};
|
||||||
} else if (IrisSafeguard.instance.warningmode) {
|
|
||||||
colorIris = String.valueOf(C.GOLD);
|
|
||||||
colorVolmit = String.valueOf(C.GOLD);
|
|
||||||
colorVersion = String.valueOf(C.GOLD);
|
|
||||||
} else {
|
|
||||||
colorIris = String.valueOf(C.IRIS);
|
|
||||||
colorVolmit = "<rainbow>";
|
|
||||||
colorVersion = String.valueOf(C.IRIS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] info = {
|
String[] splashstable = {
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
padd2 + colorIris + " Iris",
|
|
||||||
padd2 + C.GRAY + " by " + colorVolmit + "Volmit Software",
|
|
||||||
padd2 + C.GRAY + " v" + colorVersion + getDescription().getVersion()
|
|
||||||
};
|
|
||||||
|
|
||||||
String[] splash = {
|
|
||||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + colorIris + " .(((()))). ",
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ",
|
||||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + colorIris + " .((((((())))))). ",
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ",
|
||||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + colorIris + " ((((((((())))))))) " + C.GRAY + " @",
|
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.IRIS + " ((((((((())))))))) " + C.GRAY + " @",
|
||||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + colorIris + " ((((((((-))))))))) " + C.GRAY + " @@",
|
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.IRIS + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||||
padd + C.GRAY + "@@@&&" + colorIris + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
padd + C.GRAY + "@@@&&" + C.IRIS + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||||
padd + C.GRAY + "@@" + colorIris + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
padd + C.GRAY + "@@" + C.IRIS + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||||
padd + C.GRAY + "@" + colorIris + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
padd + C.GRAY + "@" + C.IRIS + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||||
padd + C.GRAY + "" + colorIris + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
padd + C.GRAY + "" + C.IRIS + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||||
padd + C.GRAY + "" + colorIris + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
};
|
};
|
||||||
|
|
||||||
setupChecks();
|
String[] splashunstable = {
|
||||||
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.RED + " .(((()))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.RED + " .((((((())))))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.RED + " ((((((((())))))))) " + C.GRAY + " @",
|
||||||
|
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.RED + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||||
|
padd + C.GRAY + "@@@&&" + C.RED + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||||
|
padd + C.GRAY + "@@" + C.RED + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||||
|
padd + C.GRAY + "@" + C.RED + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.RED + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.RED + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
|
};
|
||||||
|
String[] splashwarning = {
|
||||||
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.GOLD + " .(((()))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.GOLD + " .((((((())))))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.GOLD + " ((((((((())))))))) " + C.GRAY + " @",
|
||||||
|
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.GOLD + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||||
|
padd + C.GRAY + "@@@&&" + C.GOLD + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||||
|
padd + C.GRAY + "@@" + C.GOLD + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||||
|
padd + C.GRAY + "@" + C.GOLD + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.GOLD + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.GOLD + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
|
};
|
||||||
|
String[] splash;
|
||||||
|
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||||
|
if (unstablemode) {
|
||||||
|
splash = splashunstable;
|
||||||
|
} else if (warningmode) {
|
||||||
|
splash = splashwarning;
|
||||||
|
} else {
|
||||||
|
splash = splashstable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passedserversoftware) {
|
||||||
|
Iris.info("Server type & version: " + C.RED + Bukkit.getVersion());
|
||||||
|
} else { Iris.info("Server type & version: " + Bukkit.getVersion()); }
|
||||||
Iris.info("Java: " + getJava());
|
Iris.info("Java: " + getJava());
|
||||||
if (!instance.getServer().getVersion().contains("Purpur")) {
|
if (!instance.getServer().getVersion().contains("Purpur")) {
|
||||||
if (instance.getServer().getVersion().contains("Spigot") && instance.getServer().getVersion().contains("Bukkit")) {
|
if (instance.getServer().getVersion().contains("Spigot") && instance.getServer().getVersion().contains("Bukkit")) {
|
||||||
Iris.info(C.RED + " Iris requires paper or above to function properly..");
|
Iris.info(C.RED + " Iris requires paper or above to function properly..");
|
||||||
} else {
|
} else {
|
||||||
Iris.info(C.YELLOW + "Purpur is recommended to use with iris.");
|
Iris.info(C.YELLOW + "Purpur is recommended to use with iris.");
|
||||||
}
|
}
|
||||||
@@ -923,6 +867,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
Iris.info("Bukkit distro: " + Bukkit.getName());
|
Iris.info("Bukkit distro: " + Bukkit.getName());
|
||||||
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
||||||
|
setupChecks();
|
||||||
printPacks();
|
printPacks();
|
||||||
|
|
||||||
for (int i = 0; i < info.length; i++) {
|
for (int i = 0; i < info.length; i++) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,7 +24,9 @@ import com.volmit.iris.util.io.IO;
|
|||||||
import com.volmit.iris.util.json.JSONException;
|
import com.volmit.iris.util.json.JSONException;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -33,7 +35,6 @@ import java.io.IOException;
|
|||||||
@Data
|
@Data
|
||||||
public class IrisSettings {
|
public class IrisSettings {
|
||||||
public static IrisSettings settings;
|
public static IrisSettings settings;
|
||||||
private IrisSafeGuard safeguard = new IrisSafeGuard();
|
|
||||||
private IrisSettingsGeneral general = new IrisSettingsGeneral();
|
private IrisSettingsGeneral general = new IrisSettingsGeneral();
|
||||||
private IrisSettingsWorld world = new IrisSettingsWorld();
|
private IrisSettingsWorld world = new IrisSettingsWorld();
|
||||||
private IrisSettingsGUI gui = new IrisSettingsGUI();
|
private IrisSettingsGUI gui = new IrisSettingsGUI();
|
||||||
@@ -42,9 +43,7 @@ public class IrisSettings {
|
|||||||
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
||||||
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
||||||
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
||||||
private IrisWorldDump worldDump = new IrisWorldDump();
|
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
||||||
private IrisWorldSettings irisWorldSettings = new IrisWorldSettings();
|
|
||||||
private IrisServerSettings server = new IrisServerSettings();
|
|
||||||
|
|
||||||
public static int getThreadCount(int c) {
|
public static int getThreadCount(int c) {
|
||||||
return switch (c) {
|
return switch (c) {
|
||||||
@@ -105,12 +104,6 @@ public class IrisSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class IrisSafeGuard {
|
|
||||||
public boolean ignoreBootMode = false;
|
|
||||||
public boolean userUnstableWarning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsAutoconfiguration {
|
public static class IrisSettingsAutoconfiguration {
|
||||||
public boolean configureSpigotTimeoutTime = true;
|
public boolean configureSpigotTimeoutTime = true;
|
||||||
@@ -141,21 +134,50 @@ public class IrisSettings {
|
|||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsConcurrency {
|
public static class IrisSettingsConcurrency {
|
||||||
public int parallelism = -1;
|
public int parallelism = -1;
|
||||||
|
public int worldGenParallelism = -1;
|
||||||
|
|
||||||
|
public int getWorldGenThreads() {
|
||||||
|
return getThreadCount(worldGenParallelism);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsPerformance {
|
public static class IrisSettingsPerformance {
|
||||||
public boolean trimMantleInStudio = false;
|
public boolean trimMantleInStudio = false;
|
||||||
public int mantleKeepAlive = 30;
|
public int mantleKeepAlive = 30;
|
||||||
public int headlessKeepAlive = 10;
|
|
||||||
public int cacheSize = 4_096;
|
public int cacheSize = 4_096;
|
||||||
public int resourceLoaderCacheSize = 1_024;
|
public int resourceLoaderCacheSize = 1_024;
|
||||||
public int objectLoaderCacheSize = 4_096;
|
public int objectLoaderCacheSize = 4_096;
|
||||||
public int scriptLoaderCacheSize = 512;
|
public int scriptLoaderCacheSize = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class IrisSettingsUpdater {
|
||||||
|
public double threadMultiplier = 2;
|
||||||
|
public double chunkLoadSensitivity = 0.7;
|
||||||
|
public MsRange emptyMsRange = new MsRange(80, 100);
|
||||||
|
public MsRange defaultMsRange = new MsRange(20, 40);
|
||||||
|
|
||||||
|
public double getThreadMultiplier() {
|
||||||
|
return Math.min(Math.abs(threadMultiplier), 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChunkLoadSensitivity() {
|
||||||
|
return Math.min(chunkLoadSensitivity, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class MsRange {
|
||||||
|
public int min = 20;
|
||||||
|
public int max = 40;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGeneral {
|
public static class IrisSettingsGeneral {
|
||||||
|
public boolean DoomsdayAnnihilationSelfDestructMode = false;
|
||||||
public boolean commandSounds = true;
|
public boolean commandSounds = true;
|
||||||
public boolean debug = false;
|
public boolean debug = false;
|
||||||
public boolean disableNMS = false;
|
public boolean disableNMS = false;
|
||||||
@@ -163,12 +185,12 @@ public class IrisSettings {
|
|||||||
public boolean splashLogoStartup = true;
|
public boolean splashLogoStartup = true;
|
||||||
public boolean useConsoleCustomColors = true;
|
public boolean useConsoleCustomColors = true;
|
||||||
public boolean useCustomColorsIngame = true;
|
public boolean useCustomColorsIngame = true;
|
||||||
|
public boolean adjustVanillaHeight = false;
|
||||||
public String forceMainWorld = "";
|
public String forceMainWorld = "";
|
||||||
public int spinh = -20;
|
public int spinh = -20;
|
||||||
public int spins = 7;
|
public int spins = 7;
|
||||||
public int spinb = 8;
|
public int spinb = 8;
|
||||||
public String cartographerMessage = "Iris does not allow cartographers in its world due to crashes.";
|
public String cartographerMessage = "Iris does not allow cartographers in its world due to crashes.";
|
||||||
public String[] dataPackPaths = new String[0];
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
@@ -198,28 +220,4 @@ public class IrisSettings {
|
|||||||
public boolean disableTimeAndWeather = true;
|
public boolean disableTimeAndWeather = true;
|
||||||
public boolean autoStartDefaultStudio = false;
|
public boolean autoStartDefaultStudio = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class IrisWorldDump {
|
|
||||||
public int mcaCacheSize = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class IrisServerSettings {
|
|
||||||
public boolean active = false;
|
|
||||||
public int port = 1337;
|
|
||||||
public String[] remote = new String[0];
|
|
||||||
|
|
||||||
public boolean isRemote() {
|
|
||||||
return remote.length != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: Goal:Have these as the default world settings and when put in bukkit.yml it will again overwrite that world from these.
|
|
||||||
@Data
|
|
||||||
public static class IrisWorldSettings {
|
|
||||||
public boolean dynamicEntityAdjustments;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,19 +21,35 @@ package com.volmit.iris.core;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.engine.object.IrisRange;
|
||||||
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.KSet;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.misc.ServerProperties;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.volmit.iris.core.nms.datapack.IDataFixer.Dimension.*;
|
||||||
|
|
||||||
public class ServerConfigurator {
|
public class ServerConfigurator {
|
||||||
public static void configure() {
|
public static void configure() {
|
||||||
@@ -45,6 +61,8 @@ public class ServerConfigurator {
|
|||||||
if (s.isConfigurePaperWatchdogDelay()) {
|
if (s.isConfigurePaperWatchdogDelay()) {
|
||||||
J.attempt(ServerConfigurator::increasePaperWatchdog);
|
J.attempt(ServerConfigurator::increasePaperWatchdog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
installDataPacks(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
||||||
@@ -60,7 +78,6 @@ public class ServerConfigurator {
|
|||||||
f.save(spigotConfig);
|
f.save(spigotConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
||||||
File spigotConfig = new File("config/paper-global.yml");
|
File spigotConfig = new File("config/paper-global.yml");
|
||||||
FileConfiguration f = new YamlConfiguration();
|
FileConfiguration f = new YamlConfiguration();
|
||||||
@@ -75,58 +92,196 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File[] getDataPacksFolder() {
|
private static KList<File> getDatapacksFolder() {
|
||||||
KList<File> files = new KList<>();
|
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
|
||||||
files.add(new File("plugins/Iris/datapack"));
|
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
||||||
Arrays.stream(IrisSettings.get().getGeneral().dataPackPaths)
|
}
|
||||||
.map(File::new)
|
KList<File> worlds = new KList<>();
|
||||||
.forEach(files::add);
|
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
|
||||||
return files.toArray(File[]::new);
|
if (worlds.isEmpty()) worlds.add(new File(Bukkit.getWorldContainer(), ServerProperties.LEVEL_NAME + "/datapacks"));
|
||||||
|
return worlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setupDataPack() {
|
public static void installDataPacks(boolean fullInstall) {
|
||||||
File packs = new File("plugins/Iris/packs");
|
installDataPacks(DataVersion.getDefault(), fullInstall);
|
||||||
if (!packs.exists()) {
|
}
|
||||||
disableDataPack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (File i : packs.listFiles()) {
|
|
||||||
if (!i.isDirectory()) continue;
|
|
||||||
|
|
||||||
Iris.verbose("Checking Pack: " + i.getPath());
|
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
|
||||||
IrisData data = IrisData.get(i);
|
Iris.info("Checking Data Packs...");
|
||||||
File dims = new File(i, "dimensions");
|
DimensionHeight height = new DimensionHeight(fixer);
|
||||||
|
KList<File> folders = getDatapacksFolder();
|
||||||
|
KMap<String, KSet<String>> biomes = new KMap<>();
|
||||||
|
|
||||||
if (dims.exists()) {
|
allPacks().flatMap(height::merge)
|
||||||
for (File j : dims.listFiles((f, s) -> s.endsWith(".json"))) {
|
.parallel()
|
||||||
if (!j.isFile()) continue;
|
.forEach(dim -> {
|
||||||
IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]);
|
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
||||||
if (dim == null) continue;
|
dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>()));
|
||||||
|
});
|
||||||
|
IrisDimension.writeShared(folders, height);
|
||||||
|
|
||||||
dim.getAllBiomes(() -> data)
|
Iris.info("Data Packs Setup!");
|
||||||
|
|
||||||
|
if (fullInstall)
|
||||||
|
verifyDataPacksPost(IrisSettings.get().getAutoConfiguration().isAutoRestartOnCustomBiomeInstall());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyDataPacksPost(boolean allowRestarting) {
|
||||||
|
boolean bad = allPacks()
|
||||||
|
.map(data -> {
|
||||||
|
Iris.verbose("Checking Pack: " + data.getDataFolder().getPath());
|
||||||
|
var loader = data.getDimensionLoader();
|
||||||
|
return loader.loadAll(loader.getPossibleKeys())
|
||||||
.stream()
|
.stream()
|
||||||
.map(IrisBiome::getCustomDerivitives)
|
.map(ServerConfigurator::verifyDataPackInstalled)
|
||||||
.filter(Objects::nonNull)
|
.toList()
|
||||||
.flatMap(KList::stream)
|
.contains(false);
|
||||||
.forEach(b -> INMS.get().registerBiome(dim.getLoadKey(), b, false));
|
})
|
||||||
|
.toList()
|
||||||
|
.contains(true);
|
||||||
|
if (!bad) return;
|
||||||
|
|
||||||
|
|
||||||
|
if (allowRestarting) {
|
||||||
|
restart();
|
||||||
|
} else if (INMS.get().supportsDataPacks()) {
|
||||||
|
Iris.error("============================================================================");
|
||||||
|
Iris.error(C.ITALIC + "You need to restart your server to properly generate custom biomes.");
|
||||||
|
Iris.error(C.ITALIC + "By continuing, Iris will use backup biomes in place of the custom biomes.");
|
||||||
|
Iris.error("----------------------------------------------------------------------------");
|
||||||
|
Iris.error(C.UNDERLINE + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!");
|
||||||
|
Iris.error("============================================================================");
|
||||||
|
|
||||||
|
for (Player i : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (i.isOp() || i.hasPermission("iris.all")) {
|
||||||
|
VolmitSender sender = new VolmitSender(i, Iris.instance.getTag("WARNING"));
|
||||||
|
sender.sendMessage("There are some Iris Packs that have custom biomes in them");
|
||||||
|
sender.sendMessage("You need to restart your server to use these packs.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
J.sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void restart() {
|
||||||
|
J.s(() -> {
|
||||||
|
Iris.warn("New data pack entries have been installed in Iris! Restarting server!");
|
||||||
|
Iris.warn("This will only happen when your pack changes (updates/first time setup)");
|
||||||
|
Iris.warn("(You can disable this auto restart in iris settings)");
|
||||||
|
J.s(() -> {
|
||||||
|
Iris.warn("Looks like the restart command didn't work. Stopping the server instead!");
|
||||||
|
Bukkit.shutdown();
|
||||||
|
}, 100);
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean verifyDataPackInstalled(IrisDimension dimension) {
|
||||||
|
KSet<String> keys = new KSet<>();
|
||||||
|
boolean warn = false;
|
||||||
|
|
||||||
|
for (IrisBiome i : dimension.getAllBiomes(dimension::getLoader)) {
|
||||||
|
if (i.isCustom()) {
|
||||||
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
|
keys.add(dimension.getLoadKey() + ":" + j.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dumpDataPack();
|
String key = getWorld(dimension.getLoader());
|
||||||
}
|
if (key == null) key = dimension.getLoadKey();
|
||||||
|
else key += "/" + dimension.getLoadKey();
|
||||||
|
|
||||||
public static void dumpDataPack() {
|
if (!INMS.get().supportsDataPacks()) {
|
||||||
if (!INMS.get().dumpRegistry(getDataPacksFolder())) {
|
if (!keys.isEmpty()) {
|
||||||
return;
|
Iris.warn("===================================================================================");
|
||||||
|
Iris.warn("Pack " + key + " has " + keys.size() + " custom biome(s). ");
|
||||||
|
Iris.warn("Your server version does not yet support datapacks for iris.");
|
||||||
|
Iris.warn("The world will generate these biomes as backup biomes.");
|
||||||
|
Iris.warn("====================================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
disableDataPack();
|
|
||||||
|
for (String i : keys) {
|
||||||
|
Object o = INMS.get().getCustomBiomeBaseFor(i);
|
||||||
|
|
||||||
|
if (o == null) {
|
||||||
|
Iris.warn("The Biome " + i + " is not registered on the server.");
|
||||||
|
warn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warn) {
|
||||||
|
Iris.error("The Pack " + key + " is INCAPABLE of generating custom biomes");
|
||||||
|
Iris.error("If not done automatically, restart your server before generating with this pack!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return !warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void disableDataPack() {
|
public static Stream<IrisData> allPacks() {
|
||||||
var packs = INMS.get().getPackRepository();
|
return Stream.concat(listFiles(new File("plugins/Iris/packs")),
|
||||||
packs.reload();
|
listFiles(Bukkit.getWorldContainer()).map(w -> new File(w, "iris/pack")))
|
||||||
if (!packs.removePack("file/iris"))
|
.filter(File::isDirectory)
|
||||||
return;
|
.map(IrisData::get);
|
||||||
packs.reloadWorldData();
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getWorld(@NonNull IrisData data) {
|
||||||
|
String worldContainer = Bukkit.getWorldContainer().getAbsolutePath();
|
||||||
|
if (!worldContainer.endsWith(File.separator)) worldContainer += File.separator;
|
||||||
|
|
||||||
|
String path = data.getDataFolder().getAbsolutePath();
|
||||||
|
if (!path.startsWith(worldContainer)) return null;
|
||||||
|
int l = path.endsWith(File.separator) ? 11 : 10;
|
||||||
|
return path.substring(worldContainer.length(), path.length() - l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<File> listFiles(File parent) {
|
||||||
|
var files = parent.listFiles();
|
||||||
|
return files == null ? Stream.empty() : Arrays.stream(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class DimensionHeight {
|
||||||
|
private final IDataFixer fixer;
|
||||||
|
private IrisRange overworld = new IrisRange();
|
||||||
|
private IrisRange nether = new IrisRange();
|
||||||
|
private IrisRange end = new IrisRange();
|
||||||
|
private int logicalOverworld = 0;
|
||||||
|
private int logicalNether = 0;
|
||||||
|
private int logicalEnd = 0;
|
||||||
|
|
||||||
|
public Stream<IrisDimension> merge(IrisData data) {
|
||||||
|
Iris.verbose("Checking Pack: " + data.getDataFolder().getPath());
|
||||||
|
var loader = data.getDimensionLoader();
|
||||||
|
return loader.loadAll(loader.getPossibleKeys())
|
||||||
|
.stream()
|
||||||
|
.peek(this::merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void merge(IrisDimension dimension) {
|
||||||
|
overworld.merge(dimension.getDimensionHeight());
|
||||||
|
nether.merge(dimension.getDimensionHeight());
|
||||||
|
end.merge(dimension.getDimensionHeight());
|
||||||
|
|
||||||
|
logicalOverworld = Math.max(logicalOverworld, dimension.getLogicalHeight());
|
||||||
|
logicalNether = Math.max(logicalNether, dimension.getLogicalHeightNether());
|
||||||
|
logicalEnd = Math.max(logicalEnd, dimension.getLogicalHeightEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String overworldType() {
|
||||||
|
return fixer.createDimension(OVERRWORLD, overworld, logicalOverworld).toString(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String netherType() {
|
||||||
|
return fixer.createDimension(NETHER, nether, logicalNether).toString(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String endType() {
|
||||||
|
return fixer.createDimension(THE_END, end, logicalEnd).toString(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.commands;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.pregenerator.DeepSearchPregenerator;
|
||||||
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
|
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.util.data.Dimension;
|
||||||
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Decree(name = "DeepSearch", aliases = "search", description = "Pregenerate your Iris worlds!")
|
||||||
|
public class CommandDeepSearch implements DecreeExecutor {
|
||||||
|
public String worldName;
|
||||||
|
@Decree(description = "DeepSearch a world")
|
||||||
|
public void start(
|
||||||
|
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||||
|
int radius,
|
||||||
|
@Param(description = "The world to pregen", contextual = true)
|
||||||
|
World world,
|
||||||
|
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||||
|
Vector center
|
||||||
|
) {
|
||||||
|
|
||||||
|
worldName = world.getName();
|
||||||
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
||||||
|
if (TurboFile.exists()) {
|
||||||
|
if (DeepSearchPregenerator.getInstance() != null) {
|
||||||
|
sender().sendMessage(C.BLUE + "DeepSearch is already in progress");
|
||||||
|
Iris.info(C.YELLOW + "DeepSearch is already in progress");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
TurboFile.delete();
|
||||||
|
} catch (Exception e){
|
||||||
|
Iris.error("Failed to delete the old instance file of DeepSearch!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (sender().isPlayer() && access() == null) {
|
||||||
|
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||||
|
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||||
|
}
|
||||||
|
|
||||||
|
DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder()
|
||||||
|
.world(world)
|
||||||
|
.radiusBlocks(radius)
|
||||||
|
.position(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
File SearchGenFile = new File(worldDirectory, "DeepSearch.json");
|
||||||
|
DeepSearchPregenerator pregenerator = new DeepSearchPregenerator(DeepSearchJob, SearchGenFile);
|
||||||
|
pregenerator.start();
|
||||||
|
|
||||||
|
String msg = C.GREEN + "DeepSearch started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||||
|
sender().sendMessage(msg);
|
||||||
|
Iris.info(msg);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
sender().sendMessage(C.RED + "Epic fail. See console.");
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Stop the active DeepSearch task", aliases = "x")
|
||||||
|
public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException {
|
||||||
|
DeepSearchPregenerator DeepSearchInstance = DeepSearchPregenerator.getInstance();
|
||||||
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
File turboFile = new File(worldDirectory, "DeepSearch.json");
|
||||||
|
|
||||||
|
if (DeepSearchInstance != null) {
|
||||||
|
DeepSearchInstance.shutdownInstance(world);
|
||||||
|
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||||
|
} else if (turboFile.exists() && turboFile.delete()) {
|
||||||
|
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||||
|
} else if (turboFile.exists()) {
|
||||||
|
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
|
||||||
|
public void pause(
|
||||||
|
@Param(aliases = "world", description = "The world to pause")
|
||||||
|
World world
|
||||||
|
) {
|
||||||
|
if (TurboPregenerator.getInstance() != null) {
|
||||||
|
TurboPregenerator.setPausedTurbo(world);
|
||||||
|
sender().sendMessage(C.GREEN + "Paused/unpaused Turbo Pregen, now: " + (TurboPregenerator.isPausedTurbo(world) ? "Paused" : "Running") + ".");
|
||||||
|
} else {
|
||||||
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
||||||
|
if (TurboFile.exists()){
|
||||||
|
TurboPregenerator.loadTurboGenerator(world.getName());
|
||||||
|
sender().sendMessage(C.YELLOW + "Started DeepSearch back up!");
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.YELLOW + "No active DeepSearch tasks to pause/unpause.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,24 +19,25 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
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.core.tools.IrisWorldDump;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.framework.EnginePlayer;
|
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
import com.volmit.iris.engine.service.EngineStatusSVC;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
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;
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
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.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.mantle.TectonicPlate;
|
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
@@ -52,6 +53,8 @@ import java.io.*;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
@@ -61,22 +64,55 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
private CommandTurboPregen turboPregen;
|
private CommandTurboPregen turboPregen;
|
||||||
private CommandUpdater updater;
|
private CommandUpdater updater;
|
||||||
|
|
||||||
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, aliases = "status", sync = true)
|
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
|
||||||
public void EngineStatus() {
|
public void EngineStatus() {
|
||||||
var status = EngineStatusSVC.getStatus();
|
List<World> IrisWorlds = new ArrayList<>();
|
||||||
|
int TotalLoadedChunks = 0;
|
||||||
|
int TotalQueuedTectonicPlates = 0;
|
||||||
|
int TotalNotQueuedTectonicPlates = 0;
|
||||||
|
int TotalTectonicPlates = 0;
|
||||||
|
|
||||||
sender().sendMessage("-------------------------");
|
long lowestUnloadDuration = 0;
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Engine Status");
|
long highestUnloadDuration = 0;
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Total Engines: " + C.LIGHT_PURPLE + status.engineCount());
|
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Total Loaded Chunks: " + C.LIGHT_PURPLE + status.loadedChunks());
|
for (World world : Bukkit.getWorlds()) {
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + status.tectonicLimit());
|
try {
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Tectonic Total Plates: " + C.LIGHT_PURPLE + status.tectonicPlates());
|
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Tectonic Active Plates: " + C.LIGHT_PURPLE + status.activeTectonicPlates());
|
IrisWorlds.add(world);
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + status.queuedTectonicPlates());
|
}
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Lowest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(status.minTectonicUnloadDuration()));
|
} catch (Exception e) {
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Highest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(status.maxTectonicUnloadDuration()));
|
// no
|
||||||
sender().sendMessage(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize()));
|
}
|
||||||
sender().sendMessage("-------------------------");
|
}
|
||||||
|
|
||||||
|
for (World world : IrisWorlds) {
|
||||||
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
TotalQueuedTectonicPlates += (int) engine.getMantle().getToUnload();
|
||||||
|
TotalNotQueuedTectonicPlates += (int) engine.getMantle().getNotQueuedLoadedRegions();
|
||||||
|
TotalTectonicPlates += engine.getMantle().getLoadedRegionCount();
|
||||||
|
if (highestUnloadDuration <= (long) engine.getMantle().getTectonicDuration()) {
|
||||||
|
highestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||||
|
}
|
||||||
|
if (lowestUnloadDuration >= (long) engine.getMantle().getTectonicDuration()) {
|
||||||
|
lowestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||||
|
}
|
||||||
|
for (Chunk chunk : world.getLoadedChunks()) {
|
||||||
|
if (chunk.isLoaded()) {
|
||||||
|
TotalLoadedChunks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iris.info("-------------------------");
|
||||||
|
Iris.info(C.DARK_PURPLE + "Engine Status");
|
||||||
|
Iris.info(C.DARK_PURPLE + "Total Loaded Chunks: " + C.LIGHT_PURPLE + TotalLoadedChunks);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit());
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Total Plates: " + C.LIGHT_PURPLE + TotalTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Active Plates: " + C.LIGHT_PURPLE + TotalNotQueuedTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + TotalQueuedTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Lowest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(lowestUnloadDuration));
|
||||||
|
Iris.info(C.DARK_PURPLE + "Highest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(highestUnloadDuration));
|
||||||
|
Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize()));
|
||||||
|
Iris.info("-------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Test")
|
@Decree(description = "Test")
|
||||||
@@ -94,7 +130,7 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
for (File i : Objects.requireNonNull(tectonicplates.listFiles())) {
|
for (File i : Objects.requireNonNull(tectonicplates.listFiles())) {
|
||||||
TectonicPlate.read(maxHeight, i);
|
TectonicPlate.read(maxHeight, i);
|
||||||
c++;
|
c++;
|
||||||
sender().sendMessage("Loaded count: " + c);
|
Iris.info("Loaded count: " + c );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,40 +138,32 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
|
|
||||||
@Decree(description = "Test")
|
@Decree(description = "Test")
|
||||||
public void packBenchmark(
|
public void packBenchmark(
|
||||||
@Param(description = "The pack to bench", defaultValue = "overworld", aliases = {"pack"})
|
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
|
||||||
IrisDimension dimension,
|
IrisDimension dimension,
|
||||||
@Param(description = "The address to use", defaultValue = "-")
|
@Param(description = "Radius in regions", defaultValue = "2048")
|
||||||
String address,
|
int radius,
|
||||||
@Param(description = "Headless", defaultValue = "true")
|
@Param(description = "Open GUI while benchmarking", defaultValue = "false")
|
||||||
boolean headless,
|
boolean gui
|
||||||
@Param(description = "GUI", defaultValue = "false")
|
|
||||||
boolean gui,
|
|
||||||
@Param(description = "Diameter in regions", defaultValue = "5")
|
|
||||||
int diameter
|
|
||||||
) {
|
) {
|
||||||
int rb = diameter << 9;
|
new IrisPackBenchmarking(dimension, radius, gui);
|
||||||
Iris.info("Benchmarking pack " + dimension.getName() + " with diameter: " + rb + "(" + diameter + ")");
|
}
|
||||||
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, address.replace("-", "").trim(), diameter, headless, gui);
|
|
||||||
benchmark.runBenchmark();
|
@Decree(description = "Upgrade to another Minecraft version")
|
||||||
|
public void upgrade(
|
||||||
|
@Param(description = "The version to upgrade to", defaultValue = "latest") DataVersion version) {
|
||||||
|
sender().sendMessage(C.GREEN + "Upgrading to " + version.getVersion() + "...");
|
||||||
|
ServerConfigurator.installDataPacks(version.get(), false);
|
||||||
|
sender().sendMessage(C.GREEN + "Done upgrading! You can now update your server version to " + version.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "test")
|
@Decree(description = "test")
|
||||||
public void mca(
|
public void mca (
|
||||||
@Param(description = "String") World world) {
|
@Param(description = "String") String world) {
|
||||||
try {
|
try {
|
||||||
IrisWorldDump dump = new IrisWorldDump(world, sender());
|
File[] McaFiles = new File(world, "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
||||||
dump.start();
|
for (File mca : McaFiles) {
|
||||||
|
MCAFile MCARegion = MCAUtil.read(mca);
|
||||||
} catch (Exception e) {
|
}
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "test")
|
|
||||||
public void test() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -201,34 +229,6 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "All players in iris worlds")
|
|
||||||
public void getPlayers() {
|
|
||||||
KList<World> IrisWorlds = new KList<>();
|
|
||||||
for (World w : Bukkit.getServer().getWorlds()) {
|
|
||||||
if(IrisToolbelt.isIrisWorld(w)) {
|
|
||||||
IrisWorlds.add(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender().isPlayer()) {
|
|
||||||
sender().sendMessage(C.BLUE + "Iris Worlds: ");
|
|
||||||
for (World IrisWorld : IrisWorlds.copy()) {
|
|
||||||
sender().sendMessage(C.IRIS + "- " + IrisWorld.getName() + C.GRAY + ", " + IrisToolbelt.access(IrisWorld).getEngine().getEnginePlayers().stream().count() + " players");
|
|
||||||
for (EnginePlayer player : IrisToolbelt.access(IrisWorld).getEngine().getEnginePlayers()) {
|
|
||||||
sender().sendMessage(C.DARK_GRAY + "> " + player.getPlayer().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Iris.info(C.BLUE + "Iris Worlds: ");
|
|
||||||
for (World IrisWorld : IrisWorlds.copy()) {
|
|
||||||
Iris.info(C.IRIS + "- " + IrisWorld.getName() + C.GRAY + ", " + IrisToolbelt.access(IrisWorld).getEngine().getEnginePlayers().stream().count() + " players");
|
|
||||||
for (EnginePlayer player : IrisToolbelt.access(IrisWorld).getEngine().getEnginePlayers()) {
|
|
||||||
Iris.info(C.DARK_GRAY + "> " + player.getPlayer().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "Test the compression algorithms")
|
@Decree(description = "Test the compression algorithms")
|
||||||
public void compression(
|
public void compression(
|
||||||
@Param(description = "base IrisWorld") World world,
|
@Param(description = "base IrisWorld") World world,
|
||||||
@@ -244,12 +244,13 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
if (!file.exists()) return;
|
if (!file.exists()) return;
|
||||||
|
|
||||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
if (engine != null) {
|
if(engine != null) {
|
||||||
int height = engine.getTarget().getHeight();
|
int height = engine.getTarget().getHeight();
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(1);
|
||||||
VolmitSender sender = sender();
|
VolmitSender sender = sender();
|
||||||
new Thread(() -> {
|
service.submit(() -> {
|
||||||
try {
|
try {
|
||||||
DataInputStream raw = new DataInputStream(new FileInputStream(file));
|
CountingDataInputStream raw = CountingDataInputStream.wrap(new FileInputStream(file));
|
||||||
TectonicPlate plate = new TectonicPlate(height, raw);
|
TectonicPlate plate = new TectonicPlate(height, raw);
|
||||||
raw.close();
|
raw.close();
|
||||||
|
|
||||||
@@ -268,7 +269,7 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = tmp.length();
|
size = tmp.length();
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
DataInputStream din = createInput(tmp, algorithm);
|
CountingDataInputStream din = createInput(tmp, algorithm);
|
||||||
new TectonicPlate(height, din);
|
new TectonicPlate(height, din);
|
||||||
din.close();
|
din.close();
|
||||||
d2 += System.currentTimeMillis() - start;
|
d2 += System.currentTimeMillis() - start;
|
||||||
@@ -276,21 +277,22 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
IO.delete(folder);
|
IO.delete(folder);
|
||||||
sender.sendMessage(algorithm + " is " + Form.fileSize(size) + " big after compression");
|
sender.sendMessage(algorithm + " is " + Form.fileSize(size) + " big after compression");
|
||||||
sender.sendMessage(algorithm + " Took " + d2 / amount + "ms to read");
|
sender.sendMessage(algorithm + " Took " + d2/amount + "ms to read");
|
||||||
sender.sendMessage(algorithm + " Took " + d1 / amount + "ms to write");
|
sender.sendMessage(algorithm + " Took " + d1/amount + "ms to write");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}, "Compression Test").start();
|
});
|
||||||
} else {
|
service.shutdown();
|
||||||
|
} else {
|
||||||
Iris.info(C.RED + "Engine is null!");
|
Iris.info(C.RED + "Engine is null!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataInputStream createInput(File file, String algorithm) throws Throwable {
|
private CountingDataInputStream createInput(File file, String algorithm) throws Throwable {
|
||||||
FileInputStream in = new FileInputStream(file);
|
FileInputStream in = new FileInputStream(file);
|
||||||
|
|
||||||
return new DataInputStream(switch (algorithm) {
|
return CountingDataInputStream.wrap(switch (algorithm) {
|
||||||
case "gzip" -> new GZIPInputStream(in);
|
case "gzip" -> new GZIPInputStream(in);
|
||||||
case "lz4f" -> new LZ4FrameInputStream(in);
|
case "lz4f" -> new LZ4FrameInputStream(in);
|
||||||
case "lz4b" -> new LZ4BlockInputStream(in);
|
case "lz4b" -> new LZ4BlockInputStream(in);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,12 +21,14 @@ package com.volmit.iris.core.commands;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisBenchmarking;
|
import com.volmit.iris.core.tools.IrisBenchmarking;
|
||||||
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.core.safeguard.UtilsSFG;
|
||||||
import com.volmit.iris.engine.object.IrisWorld;
|
import com.volmit.iris.engine.object.IrisWorld;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
||||||
@@ -40,9 +42,6 @@ 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.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
|
||||||
import org.apache.commons.io.filefilter.TrueFileFilter;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
@@ -55,23 +54,21 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.volmit.iris.Iris.service;
|
import static com.volmit.iris.Iris.service;
|
||||||
import static com.volmit.iris.core.service.EditSVC.deletingWorld;
|
import static com.volmit.iris.core.service.EditSVC.deletingWorld;
|
||||||
import static com.volmit.iris.core.tools.IrisBenchmarking.inProgress;
|
import static com.volmit.iris.core.tools.IrisBenchmarking.inProgress;
|
||||||
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
|
||||||
|
import static com.volmit.iris.core.safeguard.ServerBootSFG.incompatibilities;
|
||||||
import static org.bukkit.Bukkit.getServer;
|
import static org.bukkit.Bukkit.getServer;
|
||||||
|
|
||||||
@Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
|
@Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
|
||||||
public class CommandIris implements DecreeExecutor {
|
public class CommandIris implements DecreeExecutor {
|
||||||
public static boolean worldCreation = false;
|
|
||||||
String WorldEngine;
|
|
||||||
String worldNameToCheck = "YourWorldName";
|
|
||||||
VolmitSender sender = Iris.getSender();
|
|
||||||
private CommandStudio studio;
|
private CommandStudio studio;
|
||||||
private CommandPregen pregen;
|
private CommandPregen pregen;
|
||||||
|
private CommandLazyPregen lazyPregen;
|
||||||
private CommandSettings settings;
|
private CommandSettings settings;
|
||||||
private CommandObject object;
|
private CommandObject object;
|
||||||
private CommandJigsaw jigsaw;
|
private CommandJigsaw jigsaw;
|
||||||
@@ -80,19 +77,10 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
private CommandFind find;
|
private CommandFind find;
|
||||||
private CommandSupport support;
|
private CommandSupport support;
|
||||||
private CommandDeveloper developer;
|
private CommandDeveloper developer;
|
||||||
|
public static boolean worldCreation = false;
|
||||||
public static boolean deleteDirectory(File dir) {
|
String WorldEngine;
|
||||||
if (dir.isDirectory()) {
|
String worldNameToCheck = "YourWorldName";
|
||||||
File[] children = dir.listFiles();
|
VolmitSender sender = Iris.getSender();
|
||||||
for (int i = 0; i < children.length; i++) {
|
|
||||||
boolean success = deleteDirectory(children[i]);
|
|
||||||
if (!success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dir.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "Create a new world", aliases = {"+", "c"})
|
@Decree(description = "Create a new world", aliases = {"+", "c"})
|
||||||
public void create(
|
public void create(
|
||||||
@@ -101,23 +89,36 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
||||||
IrisDimension type,
|
IrisDimension type,
|
||||||
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
||||||
long seed,
|
long seed
|
||||||
@Param(description = "The radius of chunks to generate in headless mode (-1 to disable)", defaultValue = "10", aliases = "radius")
|
|
||||||
int headlessRadius,
|
|
||||||
@Param(description = "If it should convert the dimension to match the vanilla height system.", defaultValue = "false")
|
|
||||||
boolean vanillaheight
|
|
||||||
) {
|
) {
|
||||||
|
if(sender() instanceof Player) {
|
||||||
if (name.equals("iris")) {
|
if (incompatibilities.get("Multiverse-Core")) {
|
||||||
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
|
sender().sendMessage(C.RED + "Your server has an incompatibility that may corrupt all worlds on the server if not handled properly.");
|
||||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
sender().sendMessage(C.RED + "it is strongly advised for you to take action. see log for full detail");
|
||||||
return;
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
}
|
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||||
if (name.equals("Benchmark")) {
|
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
sender().sendMessage(C.RED + "You cannot use the world name \"Benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs.");
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
}
|
||||||
return;
|
if (unstablemode && !incompatibilities.get("Multiverse-Core")) {
|
||||||
|
sender().sendMessage(C.RED + "Your server is experiencing an incompatibility with the Iris plugin.");
|
||||||
|
sender().sendMessage(C.RED + "Please rectify this problem to avoid further complications.");
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||||
|
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (name.equals("iris")) {
|
||||||
|
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
|
||||||
|
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name.equals("Benchmark")) {
|
||||||
|
sender().sendMessage(C.RED + "You cannot use the world name \"Benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs.");
|
||||||
|
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (new File(Bukkit.getWorldContainer(), name).exists()) {
|
if (new File(Bukkit.getWorldContainer(), name).exists()) {
|
||||||
sender().sendMessage(C.RED + "That folder already exists!");
|
sender().sendMessage(C.RED + "That folder already exists!");
|
||||||
@@ -132,7 +133,6 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
.seed(seed)
|
.seed(seed)
|
||||||
.sender(sender())
|
.sender(sender())
|
||||||
.studio(false)
|
.studio(false)
|
||||||
.headlessRadius(headlessRadius)
|
|
||||||
.create();
|
.create();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
||||||
@@ -175,6 +175,16 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
|
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo Move to React
|
||||||
|
@Decree(description = "Benchmark your server", origin = DecreeOrigin.CONSOLE)
|
||||||
|
public void serverbenchmark() throws InterruptedException {
|
||||||
|
if(!inProgress) {
|
||||||
|
IrisBenchmarking.runBenchmark();
|
||||||
|
} else {
|
||||||
|
Iris.info(C.RED + "Benchmark already is in progress.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/todo
|
/todo
|
||||||
@Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE)
|
@Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE)
|
||||||
@@ -188,16 +198,6 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
IrisPackBenchmarking.runBenchmark();
|
IrisPackBenchmarking.runBenchmark();
|
||||||
} */
|
} */
|
||||||
|
|
||||||
//todo Move to React
|
|
||||||
@Decree(description = "Benchmark your server", origin = DecreeOrigin.CONSOLE)
|
|
||||||
public void serverbenchmark() throws InterruptedException {
|
|
||||||
if (!inProgress) {
|
|
||||||
IrisBenchmarking.runBenchmark();
|
|
||||||
} else {
|
|
||||||
Iris.info(C.RED + "Benchmark already is in progress.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
|
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
|
||||||
public void height() {
|
public void height() {
|
||||||
if (sender().isPlayer()) {
|
if (sender().isPlayer()) {
|
||||||
@@ -235,20 +235,20 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
if (sender().isPlayer()) {
|
if (sender().isPlayer()) {
|
||||||
sender().sendMessage(C.BLUE + "Iris Worlds: ");
|
sender().sendMessage(C.BLUE + "Iris Worlds: ");
|
||||||
for (World IrisWorld : IrisWorlds.copy()) {
|
for (World IrisWorld : IrisWorlds.copy()) {
|
||||||
sender().sendMessage(C.IRIS + "- " + IrisWorld.getName());
|
sender().sendMessage(C.IRIS + "- " +IrisWorld.getName());
|
||||||
}
|
}
|
||||||
sender().sendMessage(C.GOLD + "Bukkit Worlds: ");
|
sender().sendMessage(C.GOLD + "Bukkit Worlds: ");
|
||||||
for (World BukkitWorld : BukkitWorlds.copy()) {
|
for (World BukkitWorld : BukkitWorlds.copy()) {
|
||||||
sender().sendMessage(C.GRAY + "- " + BukkitWorld.getName());
|
sender().sendMessage(C.GRAY + "- " +BukkitWorld.getName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Iris.info(C.BLUE + "Iris Worlds: ");
|
Iris.info(C.BLUE + "Iris Worlds: ");
|
||||||
for (World IrisWorld : IrisWorlds.copy()) {
|
for (World IrisWorld : IrisWorlds.copy()) {
|
||||||
Iris.info(C.IRIS + "- " + IrisWorld.getName());
|
Iris.info(C.IRIS + "- " +IrisWorld.getName());
|
||||||
}
|
}
|
||||||
Iris.info(C.GOLD + "Bukkit Worlds: ");
|
Iris.info(C.GOLD + "Bukkit Worlds: ");
|
||||||
for (World BukkitWorld : BukkitWorlds.copy()) {
|
for (World BukkitWorld : BukkitWorlds.copy()) {
|
||||||
Iris.info(C.GRAY + "- " + BukkitWorld.getName());
|
Iris.info(C.GRAY + "- " +BukkitWorld.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -266,6 +266,17 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
||||||
|
|
||||||
|
if (!IrisToolbelt.evacuate(world)) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to evacuate world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Bukkit.unloadWorld(world, false)) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to unload world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (IrisToolbelt.removeWorld(world)) {
|
if (IrisToolbelt.removeWorld(world)) {
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
||||||
@@ -278,27 +289,45 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
IrisToolbelt.evacuate(world, "Deleting world");
|
IrisToolbelt.evacuate(world, "Deleting world");
|
||||||
deletingWorld = true;
|
deletingWorld = true;
|
||||||
Bukkit.unloadWorld(world, false);
|
if (!delete) {
|
||||||
int retries = 12;
|
deletingWorld = false;
|
||||||
if (delete) {
|
return;
|
||||||
|
}
|
||||||
|
VolmitSender sender = sender();
|
||||||
|
J.a(() -> {
|
||||||
|
int retries = 12;
|
||||||
|
|
||||||
if (deleteDirectory(world.getWorldFolder())) {
|
if (deleteDirectory(world.getWorldFolder())) {
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while(true){
|
||||||
if (deleteDirectory(world.getWorldFolder())) {
|
if (deleteDirectory(world.getWorldFolder())){
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
retries--;
|
retries--;
|
||||||
if (retries == 0) {
|
if (retries == 0){
|
||||||
sender().sendMessage(C.RED + "Failed to remove world folder");
|
sender.sendMessage(C.RED + "Failed to remove world folder");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
J.sleep(3000);
|
J.sleep(3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
deletingWorld = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deleteDirectory(File dir) {
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
File[] children = dir.listFiles();
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
boolean success = deleteDirectory(children[i]);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
deletingWorld = false;
|
return dir.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Updates all chunk in the specified world")
|
@Decree(description = "Updates all chunk in the specified world")
|
||||||
@@ -384,7 +413,7 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
) {
|
) {
|
||||||
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
||||||
if (pack.equals("overworld")) {
|
if (pack.equals("overworld")) {
|
||||||
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
|
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + INMS.OVERWORLD_TAG + "/overworld.zip";
|
||||||
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
||||||
} else {
|
} else {
|
||||||
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
||||||
@@ -444,8 +473,8 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
|
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Unload an Iris World", sync = true)
|
@Decree(description = "Unload an Iris World", origin = DecreeOrigin.PLAYER, sync = true)
|
||||||
public void unload(
|
public void unloadWorld(
|
||||||
@Param(description = "The world to unload")
|
@Param(description = "The world to unload")
|
||||||
World world
|
World world
|
||||||
) {
|
) {
|
||||||
@@ -465,76 +494,61 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Load an Iris World", origin = DecreeOrigin.PLAYER, sync = true, aliases = {"import"})
|
@Decree(description = "Load an Iris World", origin = DecreeOrigin.PLAYER, sync = true, aliases = {"import"})
|
||||||
public void load(
|
public void loadWorld(
|
||||||
@Param(description = "The name of the world to load")
|
@Param(description = "The name of the world to load")
|
||||||
String world
|
String world
|
||||||
) {
|
) {
|
||||||
|
World worldloaded = Bukkit.getWorld(world);
|
||||||
|
worldNameToCheck = world;
|
||||||
|
boolean worldExists = doesWorldExist(worldNameToCheck);
|
||||||
|
WorldEngine = world;
|
||||||
|
|
||||||
FileConfiguration fc = new YamlConfiguration();
|
if (!worldExists) {
|
||||||
try {
|
sender().sendMessage(C.YELLOW + world + " Doesnt exist on the server.");
|
||||||
fc.load(new File("bukkit.yml"));
|
return;
|
||||||
ConfigurationSection section = fc.getConfigurationSection("worlds");
|
}
|
||||||
if (section == null) {
|
|
||||||
|
File BUKKIT_YML = new File("bukkit.yml");
|
||||||
|
String pathtodim = world + File.separator +"iris"+File.separator +"pack"+File.separator +"dimensions"+File.separator;
|
||||||
|
File directory = new File(Bukkit.getWorldContainer(), pathtodim);
|
||||||
|
|
||||||
|
String dimension = null;
|
||||||
|
if (directory.exists() && directory.isDirectory()) {
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isFile()) {
|
||||||
|
String fileName = file.getName();
|
||||||
|
if (fileName.endsWith(".json")) {
|
||||||
|
dimension = fileName.substring(0, fileName.length() - 5);
|
||||||
|
sender().sendMessage(C.BLUE + "Generator: " + dimension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.GOLD + world + " is not an iris world.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Loading world: " + world);
|
||||||
|
|
||||||
|
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
||||||
|
String gen = "Iris:" + dimension;
|
||||||
|
ConfigurationSection section = yml.contains("worlds") ? yml.getConfigurationSection("worlds") : yml.createSection("worlds");
|
||||||
|
if (!section.contains(world)) {
|
||||||
|
section.createSection(world).set("generator", gen);
|
||||||
|
try {
|
||||||
|
yml.save(BUKKIT_YML);
|
||||||
|
Iris.info("Registered \"" + world + "\" in bukkit.yml");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.error("Failed to update bukkit.yml!");
|
||||||
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String s : section.getKeys(false)) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
ConfigurationSection entry = section.getConfigurationSection(s);
|
|
||||||
if (!entry.contains("backup-generator", true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String generator = entry.getString("backup-generator");
|
|
||||||
if (!generator.startsWith("Iris")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s.equalsIgnoreCase(world)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
File worldFolder = new File(Bukkit.getWorldContainer().getPath() + "/" + s + "/iris/engine-data/");
|
|
||||||
IOFileFilter jsonFilter = org.apache.commons.io.filefilter.FileFilterUtils.suffixFileFilter(".json");
|
|
||||||
Collection<File> files = FileUtils.listFiles(worldFolder, jsonFilter, TrueFileFilter.INSTANCE);
|
|
||||||
if (files.size() != 1) {
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
Iris.info(C.RED + "Failed to load " + C.GRAY + s + C.RED + ". No valid engine-data file was found.");
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : files) {
|
|
||||||
int lastDotIndex = file.getName().lastIndexOf(".");
|
|
||||||
generator = file.getName().substring(0, lastDotIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info("2 World: %s | Generator: %s", s, generator);
|
|
||||||
|
|
||||||
if (Bukkit.getWorlds().stream().anyMatch(w -> w.getName().equals(s))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
|
||||||
new WorldCreator(s)
|
|
||||||
.generator(getDefaultWorldGenerator(s, generator))
|
|
||||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
|
||||||
.createWorld();
|
|
||||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
|
||||||
break;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
Iris.info(C.RED + "Failed to load " + C.GRAY + s);
|
|
||||||
Iris.info(C.DARK_GRAY + "------------------------------------------");
|
|
||||||
}
|
|
||||||
sender().sendMessage(C.GOLD + "Failed to find world: " + C.DARK_GRAY + world);
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
checkForBukkitWorlds(world);
|
||||||
|
sender().sendMessage(C.GREEN + world + " loaded successfully.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true)
|
@Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true)
|
||||||
public void evacuate(
|
public void evacuate(
|
||||||
@Param(description = "Evacuate the world")
|
@Param(description = "Evacuate the world")
|
||||||
@@ -553,7 +567,6 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
File worldDirectory = new File(worldContainer, worldName);
|
File worldDirectory = new File(worldContainer, worldName);
|
||||||
return worldDirectory.exists() && worldDirectory.isDirectory();
|
return worldDirectory.exists() && worldDirectory.isDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForBukkitWorlds(String world) {
|
private void checkForBukkitWorlds(String world) {
|
||||||
FileConfiguration fc = new YamlConfiguration();
|
FileConfiguration fc = new YamlConfiguration();
|
||||||
try {
|
try {
|
||||||
@@ -565,7 +578,7 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
|
|
||||||
List<String> worldsToLoad = Collections.singletonList(world);
|
List<String> worldsToLoad = Collections.singletonList(world);
|
||||||
|
|
||||||
for (String s : section.getKeys(false)) {
|
for (String s : section.getKeys(false)) {
|
||||||
if (!worldsToLoad.contains(s)) {
|
if (!worldsToLoad.contains(s)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -586,17 +599,16 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||||
new WorldCreator(s)
|
WorldCreator c = new WorldCreator(s)
|
||||||
.generator(getDefaultWorldGenerator(s, generator))
|
.generator(getDefaultWorldGenerator(s, generator))
|
||||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
|
||||||
.createWorld();
|
INMS.get().createWorld(c);
|
||||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
||||||
Iris.debug("Default World Generator Called for " + worldName + " using ID: " + id);
|
Iris.debug("Default World Generator Called for " + worldName + " using ID: " + id);
|
||||||
if (worldName.equals("test")) {
|
if (worldName.equals("test")) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -60,7 +60,7 @@ public class CommandJigsaw implements DecreeExecutor {
|
|||||||
try {
|
try {
|
||||||
var world = world();
|
var world = world();
|
||||||
WorldObjectPlacer placer = new WorldObjectPlacer(world);
|
WorldObjectPlacer placer = new WorldObjectPlacer(world);
|
||||||
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation().add(0, world.getMinHeight(), 0)), new RNG());
|
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation().add(0, world.getMinHeight(), 0)), new RNG(), true);
|
||||||
VolmitSender sender = sender();
|
VolmitSender sender = sender();
|
||||||
sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2));
|
sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2));
|
||||||
ps.place(placer, failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!"));
|
ps.place(placer, failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!"));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,11 +19,16 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
@@ -34,7 +39,6 @@ import java.io.IOException;
|
|||||||
@Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!")
|
@Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!")
|
||||||
public class CommandLazyPregen implements DecreeExecutor {
|
public class CommandLazyPregen implements DecreeExecutor {
|
||||||
public String worldName;
|
public String worldName;
|
||||||
|
|
||||||
@Decree(description = "Pregenerate a world")
|
@Decree(description = "Pregenerate a world")
|
||||||
public void start(
|
public void start(
|
||||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||||
@@ -47,7 +51,7 @@ public class CommandLazyPregen implements DecreeExecutor {
|
|||||||
int cpm,
|
int cpm,
|
||||||
@Param(aliases = "silent", description = "Silent generation", defaultValue = "false")
|
@Param(aliases = "silent", description = "Silent generation", defaultValue = "false")
|
||||||
boolean silent
|
boolean silent
|
||||||
) {
|
) {
|
||||||
|
|
||||||
worldName = world.getName();
|
worldName = world.getName();
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,6 +28,8 @@ import com.volmit.iris.core.tools.IrisConverter;
|
|||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.data.registry.Materials;
|
||||||
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;
|
||||||
@@ -36,12 +38,9 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Direction;
|
import com.volmit.iris.util.math.Direction;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.misc.E;
|
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
@@ -54,7 +53,7 @@ import java.util.*;
|
|||||||
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
||||||
public class CommandObject implements DecreeExecutor {
|
public class CommandObject implements DecreeExecutor {
|
||||||
|
|
||||||
private static final Set<Material> skipBlocks = Set.of(E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS"), Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
private static final Set<Material> skipBlocks = Set.of(Materials.GRASS, Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
||||||
Material.POPPY, Material.DANDELION);
|
Material.POPPY, Material.DANDELION);
|
||||||
|
|
||||||
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
||||||
@@ -75,12 +74,14 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
Block block = world.getBlockAt(x, y, z);
|
Block block = world.getBlockAt(x, y, z);
|
||||||
|
|
||||||
//Prevent blocks being set in or bellow bedrock
|
//Prevent blocks being set in or bellow bedrock
|
||||||
if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK)
|
if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return;
|
||||||
return;
|
|
||||||
|
|
||||||
futureBlockChanges.put(block, block.getBlockData());
|
futureBlockChanges.put(block, block.getBlockData());
|
||||||
|
|
||||||
block.setBlockData(d);
|
if (d instanceof IrisCustomData data) {
|
||||||
|
block.setBlockData(data.getBase());
|
||||||
|
Iris.warn("Tried to place custom block at " + x + ", " + y + ", " + z + " which is not supported!");
|
||||||
|
} else block.setBlockData(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -377,9 +378,11 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
@Param(description = "The file to store it in, can use / for subfolders")
|
@Param(description = "The file to store it in, can use / for subfolders")
|
||||||
String name,
|
String name,
|
||||||
@Param(description = "Overwrite existing object files", defaultValue = "false", aliases = "force")
|
@Param(description = "Overwrite existing object files", defaultValue = "false", aliases = "force")
|
||||||
boolean overwrite
|
boolean overwrite,
|
||||||
|
@Param(description = "Use legacy TileState serialization if possible", defaultValue = "true")
|
||||||
|
boolean legacy
|
||||||
) {
|
) {
|
||||||
IrisObject o = WandSVC.createSchematic(player());
|
IrisObject o = WandSVC.createSchematic(player(), legacy);
|
||||||
|
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
sender().sendMessage(C.YELLOW + "You need to hold your wand!");
|
sender().sendMessage(C.YELLOW + "You need to hold your wand!");
|
||||||
@@ -438,7 +441,7 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
ObjectSVC service = Iris.service(ObjectSVC.class);
|
ObjectSVC service = Iris.service(ObjectSVC.class);
|
||||||
int actualReverts = Math.min(service.getUndos().size(), amount);
|
int actualReverts = Math.min(service.getUndos().size(), amount);
|
||||||
service.revertChanges(actualReverts);
|
service.revertChanges(actualReverts);
|
||||||
sender().sendMessage(C.BLUE + "Reverted " + actualReverts + C.BLUE + " pastes!");
|
sender().sendMessage(C.BLUE + "Reverted " + actualReverts + C.BLUE +" pastes!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DecreeOrigin.PLAYER, studio = true)
|
@Decree(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DecreeOrigin.PLAYER, studio = true)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,16 +19,9 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.pregenerator.methods.HeadlessPregenMethod;
|
|
||||||
import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod;
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.IrisEngine;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.engine.framework.EngineTarget;
|
|
||||||
import com.volmit.iris.engine.object.IrisWorld;
|
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
@@ -37,8 +30,6 @@ import com.volmit.iris.util.math.Position2;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
||||||
public class CommandPregen implements DecreeExecutor {
|
public class CommandPregen implements DecreeExecutor {
|
||||||
@Decree(description = "Pregenerate a world")
|
@Decree(description = "Pregenerate a world")
|
||||||
@@ -48,39 +39,21 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
@Param(description = "The world to pregen", contextual = true)
|
@Param(description = "The world to pregen", contextual = true)
|
||||||
World world,
|
World world,
|
||||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||||
Vector center,
|
Vector center
|
||||||
@Param(aliases = "headless", description = "Toggle headless pregeneration", defaultValue = "true")
|
) {
|
||||||
boolean headless,
|
|
||||||
@Param(aliases = "gui", description = "Enable or disable the Iris GUI.", defaultValue = "true")
|
|
||||||
boolean gui,
|
|
||||||
@Param(aliases = "resetCache", description = "If it should reset the generated region cache", defaultValue = "false")
|
|
||||||
boolean resetCache
|
|
||||||
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
if (sender().isPlayer() && access() == null) {
|
if (sender().isPlayer() && access() == null) {
|
||||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||||
}
|
}
|
||||||
radius = Math.max(radius, 1024);
|
radius = Math.max(radius, 1024);
|
||||||
int w = (radius >> 9 + 1) * 2;
|
|
||||||
|
|
||||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
|
||||||
if(!engine.setEngineHeadless()) {
|
|
||||||
Iris.error("Failed to enable headless engine!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.resetCache(resetCache)
|
.center(new Position2(center.getBlockX(), center.getBlockZ()))
|
||||||
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
|
.gui(true)
|
||||||
.gui(!GraphicsEnvironment.isHeadless() && gui)
|
.radiusX(radius)
|
||||||
.width(w)
|
.radiusZ(radius)
|
||||||
.height(w)
|
.build(), world);
|
||||||
.build(), headless ? new HeadlessPregenMethod(engine) : new HybridPregenMethod(engine.getWorld().realWorld(),
|
|
||||||
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism())), engine);
|
|
||||||
if (headless) sender().sendMessage("Using the headless Pregenerator.");
|
|
||||||
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||||
sender().sendMessage(msg);
|
sender().sendMessage(msg);
|
||||||
Iris.info(msg);
|
Iris.info(msg);
|
||||||
@@ -94,7 +67,7 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (PregeneratorJob.shutdownInstance()) {
|
if (PregeneratorJob.shutdownInstance()) {
|
||||||
Iris.info(C.BLUE + "Finishing up mca region...");
|
Iris.info( C.BLUE + "Finishing up mca region...");
|
||||||
} else {
|
} else {
|
||||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,10 +22,11 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.gui.NoiseExplorerGUI;
|
import com.volmit.iris.core.gui.NoiseExplorerGUI;
|
||||||
import com.volmit.iris.core.gui.VisionGUI;
|
import com.volmit.iris.core.gui.VisionGUI;
|
||||||
|
import com.volmit.iris.core.gui.components.IrisRenderer;
|
||||||
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
import com.volmit.iris.core.service.ConversionSVC;
|
import com.volmit.iris.core.service.ConversionSVC;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisNoiseBenchmark;
|
|
||||||
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.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
@@ -41,27 +42,33 @@ import com.volmit.iris.util.decree.annotations.Param;
|
|||||||
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.Function2;
|
import com.volmit.iris.util.function.Function2;
|
||||||
|
import com.volmit.iris.util.function.NoiseProvider;
|
||||||
|
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.json.JSONArray;
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
import com.volmit.iris.util.math.Spiraler;
|
||||||
|
import com.volmit.iris.util.noise.CNG;
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.O;
|
import com.volmit.iris.util.scheduling.O;
|
||||||
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import com.volmit.iris.util.scheduling.jobs.QueueJob;
|
import com.volmit.iris.util.scheduling.jobs.QueueJob;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -73,7 +80,6 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -83,6 +89,7 @@ import java.util.function.Supplier;
|
|||||||
public class CommandStudio implements DecreeExecutor {
|
public class CommandStudio implements DecreeExecutor {
|
||||||
private CommandFind find;
|
private CommandFind find;
|
||||||
private CommandEdit edit;
|
private CommandEdit edit;
|
||||||
|
//private CommandDeepSearch deepSearch;
|
||||||
|
|
||||||
public static String hrf(Duration duration) {
|
public static String hrf(Duration duration) {
|
||||||
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
||||||
@@ -153,6 +160,37 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Debug image")
|
||||||
|
public void printImageChannel(
|
||||||
|
@Param(name = "image", description = "Image found in the image folder inside the project")
|
||||||
|
String image,
|
||||||
|
@Param(name = "channel", description = "Image channel")
|
||||||
|
IrisImageChannel channel
|
||||||
|
) {
|
||||||
|
if (noStudio()) return;
|
||||||
|
try {
|
||||||
|
File file = new File(access().getEngine().getComplex().getData().getDataFolder(), "images/" + image);
|
||||||
|
if (!file.exists()) {
|
||||||
|
sender().sendMessage(C.RED + "The image \"" + image + "\" does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BufferedImage buffer = ImageIO.read(file);
|
||||||
|
IrisImage irisImage = new IrisImage(buffer);
|
||||||
|
File at = new File(file.getParentFile(), "debug-see-" + file.getName());
|
||||||
|
BufferedImage b = new BufferedImage(buffer.getWidth(), buffer.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
for (int i = 0; i < buffer.getWidth(); i++) {
|
||||||
|
for (int j = 0; j < buffer.getHeight(); j++) {
|
||||||
|
b.setRGB(i, j, Color.getHSBColor(0, 0, (float) irisImage.getValue(channel, i, j)).getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImageIO.write(b, "png", at);
|
||||||
|
sender().sendMessage(C.IRIS + "Debug image written to ./images for channel " + channel.name());
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender().sendMessage(C.RED + "Something went wrong.. ");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
||||||
public void regen(
|
public void regen(
|
||||||
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
||||||
@@ -169,7 +207,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
KList<Runnable> js = new KList<>();
|
KList<Runnable> js = new KList<>();
|
||||||
BurstExecutor b = MultiBurst.burst.burst();
|
BurstExecutor b = MultiBurst.burst.burst();
|
||||||
b.setMulticore(false);
|
b.setMulticore(false);
|
||||||
int rad = engine.getMantle().getRealRadius();
|
int rad = engine.getMantle().getRadius();
|
||||||
for (int i = -(radius + rad); i <= radius + rad; i++) {
|
for (int i = -(radius + rad); i <= radius + rad; i++) {
|
||||||
for (int j = -(radius + rad); j <= radius + rad; j++) {
|
for (int j = -(radius + rad); j <= radius + rad; j++) {
|
||||||
engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
|
engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
|
||||||
@@ -201,8 +239,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
while (futures.isNotEmpty()) {
|
while (futures.isNotEmpty()) {
|
||||||
try {
|
try {
|
||||||
futures.remove(0).get();
|
futures.remove(0).get();
|
||||||
} catch (InterruptedException |
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
ExecutionException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,8 +320,8 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.RED + "No studio world open!");
|
sender().sendMessage(C.RED + "No studio world open!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var provider = Iris.service(StudioSVC.class).getActiveProject().getActiveProvider();
|
Iris.service(StudioSVC.class).getActiveProject().getActiveProvider().getEngine().hotload();
|
||||||
provider.getEngine().hotload();
|
sender().sendMessage(C.GREEN + "Hotloaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Show loot if a chest were right here", origin = DecreeOrigin.PLAYER, sync = true)
|
@Decree(description = "Show loot if a chest were right here", origin = DecreeOrigin.PLAYER, sync = true)
|
||||||
@@ -300,7 +337,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
engine().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
||||||
@@ -323,7 +360,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
inv.clear();
|
inv.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
||||||
}, 0, fast ? 5 : 35));
|
}, 0, fast ? 5 : 35));
|
||||||
|
|
||||||
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
||||||
@@ -398,10 +435,25 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
|
|
||||||
|
|
||||||
@Decree(description = "Render a world map (External GUI)", aliases = "render")
|
@Decree(description = "Render a world map (External GUI)", aliases = "render")
|
||||||
public void map() {
|
public void map(
|
||||||
if (noGUI()) return;
|
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
||||||
if (noStudio()) return;
|
World world
|
||||||
VisionGUI.launch(IrisToolbelt.access(player().getWorld()).getEngine(), 0);
|
) {
|
||||||
|
if (noGUI()) {
|
||||||
|
sender().sendMessage(C.GOLD + "GUI Support isn't enabled or supported on this server.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world == null) {
|
||||||
|
if (noStudio()) return;
|
||||||
|
world = player().getWorld();
|
||||||
|
}
|
||||||
|
else if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.RED + "You need to be in or specify an Iris-generated world!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VisionGUI.launch(IrisToolbelt.access(world).getEngine(), 0);
|
||||||
sender().sendMessage(C.GREEN + "Opening map!");
|
sender().sendMessage(C.GREEN + "Opening map!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,8 +474,188 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default")
|
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default")
|
||||||
IrisDimension dimension
|
IrisDimension dimension
|
||||||
) {
|
) {
|
||||||
IrisNoiseBenchmark noiseBenchmark = new IrisNoiseBenchmark(dimension, sender());
|
// Todo: Make this more accurate
|
||||||
noiseBenchmark.runAll();
|
File pack = dimension.getLoadFile().getParentFile().getParentFile();
|
||||||
|
File report = Iris.instance.getDataFile("profile.txt");
|
||||||
|
IrisProject project = new IrisProject(pack);
|
||||||
|
IrisData data = IrisData.get(pack);
|
||||||
|
|
||||||
|
KList<String> fileText = new KList<>();
|
||||||
|
|
||||||
|
KMap<NoiseStyle, Double> styleTimings = new KMap<>();
|
||||||
|
KMap<InterpolationMethod, Double> interpolatorTimings = new KMap<>();
|
||||||
|
KMap<String, Double> generatorTimings = new KMap<>();
|
||||||
|
KMap<String, Double> biomeTimings = new KMap<>();
|
||||||
|
KMap<String, Double> regionTimings = new KMap<>();
|
||||||
|
|
||||||
|
sender().sendMessage("Calculating Performance Metrics for Noise generators");
|
||||||
|
|
||||||
|
for (NoiseStyle i : NoiseStyle.values()) {
|
||||||
|
CNG c = i.create(new RNG(i.hashCode()));
|
||||||
|
|
||||||
|
for (int j = 0; j < 3000; j++) {
|
||||||
|
c.noise(j, j + 1000, j * j);
|
||||||
|
c.noise(j, -j);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrecisionStopwatch px = PrecisionStopwatch.start();
|
||||||
|
|
||||||
|
for (int j = 0; j < 100000; j++) {
|
||||||
|
c.noise(j, j + 1000, j * j);
|
||||||
|
c.noise(j, -j);
|
||||||
|
}
|
||||||
|
|
||||||
|
styleTimings.put(i, px.getMilliseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("Noise Style Performance Impacts: ");
|
||||||
|
|
||||||
|
for (NoiseStyle i : styleTimings.sortKNumber()) {
|
||||||
|
fileText.add(i.name() + ": " + styleTimings.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("");
|
||||||
|
|
||||||
|
sender().sendMessage("Calculating Interpolator Timings...");
|
||||||
|
|
||||||
|
for (InterpolationMethod i : InterpolationMethod.values()) {
|
||||||
|
IrisInterpolator in = new IrisInterpolator();
|
||||||
|
in.setFunction(i);
|
||||||
|
in.setHorizontalScale(8);
|
||||||
|
|
||||||
|
NoiseProvider np = (x, z) -> Math.random();
|
||||||
|
|
||||||
|
for (int j = 0; j < 3000; j++) {
|
||||||
|
in.interpolate(j, -j, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrecisionStopwatch px = PrecisionStopwatch.start();
|
||||||
|
|
||||||
|
for (int j = 0; j < 100000; j++) {
|
||||||
|
in.interpolate(j + 10000, -j - 100000, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolatorTimings.put(i, px.getMilliseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("Noise Interpolator Performance Impacts: ");
|
||||||
|
|
||||||
|
for (InterpolationMethod i : interpolatorTimings.sortKNumber()) {
|
||||||
|
fileText.add(i.name() + ": " + interpolatorTimings.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("");
|
||||||
|
|
||||||
|
sender().sendMessage("Processing Generator Scores: ");
|
||||||
|
|
||||||
|
KMap<String, KList<String>> btx = new KMap<>();
|
||||||
|
|
||||||
|
for (String i : data.getGeneratorLoader().getPossibleKeys()) {
|
||||||
|
KList<String> vv = new KList<>();
|
||||||
|
IrisGenerator g = data.getGeneratorLoader().load(i);
|
||||||
|
KList<IrisNoiseGenerator> composites = g.getAllComposites();
|
||||||
|
double score = 0;
|
||||||
|
int m = 0;
|
||||||
|
for (IrisNoiseGenerator j : composites) {
|
||||||
|
m++;
|
||||||
|
score += styleTimings.get(j.getStyle().getStyle());
|
||||||
|
vv.add("Composite Noise Style " + m + " " + j.getStyle().getStyle().name() + ": " + styleTimings.get(j.getStyle().getStyle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
score += interpolatorTimings.get(g.getInterpolator().getFunction());
|
||||||
|
vv.add("Interpolator " + g.getInterpolator().getFunction().name() + ": " + interpolatorTimings.get(g.getInterpolator().getFunction()));
|
||||||
|
generatorTimings.put(i, score);
|
||||||
|
btx.put(i, vv);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("Project Generator Performance Impacts: ");
|
||||||
|
|
||||||
|
for (String i : generatorTimings.sortKNumber()) {
|
||||||
|
fileText.add(i + ": " + generatorTimings.get(i));
|
||||||
|
|
||||||
|
btx.get(i).forEach((ii) -> fileText.add(" " + ii));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("");
|
||||||
|
|
||||||
|
KMap<String, KList<String>> bt = new KMap<>();
|
||||||
|
|
||||||
|
for (String i : data.getBiomeLoader().getPossibleKeys()) {
|
||||||
|
KList<String> vv = new KList<>();
|
||||||
|
IrisBiome b = data.getBiomeLoader().load(i);
|
||||||
|
double score = 0;
|
||||||
|
|
||||||
|
int m = 0;
|
||||||
|
for (IrisBiomePaletteLayer j : b.getLayers()) {
|
||||||
|
m++;
|
||||||
|
score += styleTimings.get(j.getStyle().getStyle());
|
||||||
|
vv.add("Palette Layer " + m + ": " + styleTimings.get(j.getStyle().getStyle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
score += styleTimings.get(b.getBiomeStyle().getStyle());
|
||||||
|
vv.add("Biome Style: " + styleTimings.get(b.getBiomeStyle().getStyle()));
|
||||||
|
score += styleTimings.get(b.getChildStyle().getStyle());
|
||||||
|
vv.add("Child Style: " + styleTimings.get(b.getChildStyle().getStyle()));
|
||||||
|
biomeTimings.put(i, score);
|
||||||
|
bt.put(i, vv);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("Project Biome Performance Impacts: ");
|
||||||
|
|
||||||
|
for (String i : biomeTimings.sortKNumber()) {
|
||||||
|
fileText.add(i + ": " + biomeTimings.get(i));
|
||||||
|
|
||||||
|
bt.get(i).forEach((ff) -> fileText.add(" " + ff));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("");
|
||||||
|
|
||||||
|
for (String i : data.getRegionLoader().getPossibleKeys()) {
|
||||||
|
IrisRegion b = data.getRegionLoader().load(i);
|
||||||
|
double score = 0;
|
||||||
|
|
||||||
|
score += styleTimings.get(b.getLakeStyle().getStyle());
|
||||||
|
score += styleTimings.get(b.getRiverStyle().getStyle());
|
||||||
|
regionTimings.put(i, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("Project Region Performance Impacts: ");
|
||||||
|
|
||||||
|
for (String i : regionTimings.sortKNumber()) {
|
||||||
|
fileText.add(i + ": " + regionTimings.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText.add("");
|
||||||
|
|
||||||
|
double m = 0;
|
||||||
|
for (double i : biomeTimings.v()) {
|
||||||
|
m += i;
|
||||||
|
}
|
||||||
|
m /= biomeTimings.size();
|
||||||
|
double mm = 0;
|
||||||
|
for (double i : generatorTimings.v()) {
|
||||||
|
mm += i;
|
||||||
|
}
|
||||||
|
mm /= generatorTimings.size();
|
||||||
|
m += mm;
|
||||||
|
double mmm = 0;
|
||||||
|
for (double i : regionTimings.v()) {
|
||||||
|
mmm += i;
|
||||||
|
}
|
||||||
|
mmm /= regionTimings.size();
|
||||||
|
m += mmm;
|
||||||
|
|
||||||
|
fileText.add("Average Score: " + m);
|
||||||
|
sender().sendMessage("Score: " + Form.duration(m, 0));
|
||||||
|
|
||||||
|
try {
|
||||||
|
IO.writeAll(report, fileText.toString("\n"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
sender().sendMessage(C.GREEN + "Done! " + report.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Spawn an Iris entity", aliases = "summon", origin = DecreeOrigin.PLAYER)
|
@Decree(description = "Spawn an Iris entity", aliases = "summon", origin = DecreeOrigin.PLAYER)
|
||||||
@@ -652,7 +884,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.RED + "No studio world is open!");
|
sender().sendMessage(C.RED + "No studio world is open!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!engine().isStudio()) {
|
if (engine() == null || !engine().isStudio()) {
|
||||||
sender().sendMessage(C.RED + "You must be in a studio world!");
|
sender().sendMessage(C.RED + "You must be in a studio world!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,11 +19,46 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
|
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||||
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
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.io.IO;
|
||||||
|
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||||
import com.volmit.iris.util.misc.Hastebin;
|
import com.volmit.iris.util.misc.Hastebin;
|
||||||
|
import com.volmit.iris.util.misc.Platform;
|
||||||
|
import com.volmit.iris.util.misc.getHardware;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
|
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||||
|
import net.jpountz.lz4.LZ4FrameInputStream;
|
||||||
|
import net.jpountz.lz4.LZ4FrameOutputStream;
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
@Decree(name = "Support", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"support"})
|
@Decree(name = "Support", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"support"})
|
||||||
public class CommandSupport implements DecreeExecutor {
|
public class CommandSupport implements DecreeExecutor {
|
||||||
@@ -31,8 +66,7 @@ public class CommandSupport implements DecreeExecutor {
|
|||||||
@Decree(description = "report")
|
@Decree(description = "report")
|
||||||
public void report() {
|
public void report() {
|
||||||
try {
|
try {
|
||||||
if (sender().isPlayer())
|
if (sender().isPlayer()) sender().sendMessage(C.GOLD + "Creating report..");
|
||||||
sender().sendMessage(C.GOLD + "Creating report..");
|
|
||||||
if (!sender().isPlayer()) Iris.info(C.GOLD + "Creating report..");
|
if (!sender().isPlayer()) Iris.info(C.GOLD + "Creating report..");
|
||||||
Hastebin.enviornment(sender());
|
Hastebin.enviornment(sender());
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
|
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||||
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
@@ -34,7 +36,6 @@ import java.io.IOException;
|
|||||||
@Decree(name = "turbopregen", aliases = "turbo", description = "Pregenerate your Iris worlds!")
|
@Decree(name = "turbopregen", aliases = "turbo", description = "Pregenerate your Iris worlds!")
|
||||||
public class CommandTurboPregen implements DecreeExecutor {
|
public class CommandTurboPregen implements DecreeExecutor {
|
||||||
public String worldName;
|
public String worldName;
|
||||||
|
|
||||||
@Decree(description = "Pregenerate a world")
|
@Decree(description = "Pregenerate a world")
|
||||||
public void start(
|
public void start(
|
||||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||||
@@ -43,7 +44,7 @@ public class CommandTurboPregen implements DecreeExecutor {
|
|||||||
World world,
|
World world,
|
||||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||||
Vector center
|
Vector center
|
||||||
) {
|
) {
|
||||||
|
|
||||||
worldName = world.getName();
|
worldName = world.getName();
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
@@ -56,9 +57,9 @@ public class CommandTurboPregen implements DecreeExecutor {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
TurboFile.delete();
|
TurboFile.delete();
|
||||||
} catch (Exception e) {
|
} catch (Exception e){
|
||||||
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ public class CommandTurboPregen implements DecreeExecutor {
|
|||||||
} else {
|
} else {
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
File TurboFile = new File(worldDirectory, "turbogen.json");
|
File TurboFile = new File(worldDirectory, "turbogen.json");
|
||||||
if (TurboFile.exists()) {
|
if (TurboFile.exists()){
|
||||||
TurboPregenerator.loadTurboGenerator(world.getName());
|
TurboPregenerator.loadTurboGenerator(world.getName());
|
||||||
sender().sendMessage(C.YELLOW + "Started Turbo Pregen back up!");
|
sender().sendMessage(C.YELLOW + "Started Turbo Pregen back up!");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
@@ -27,7 +29,6 @@ import com.volmit.iris.util.decree.annotations.Decree;
|
|||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
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 org.bukkit.World;
|
|
||||||
|
|
||||||
@Decree(name = "updater", origin = DecreeOrigin.BOTH, description = "Iris World Updater")
|
@Decree(name = "updater", origin = DecreeOrigin.BOTH, description = "Iris World Updater")
|
||||||
public class CommandUpdater implements DecreeExecutor {
|
public class CommandUpdater implements DecreeExecutor {
|
||||||
@@ -42,9 +43,13 @@ public class CommandUpdater implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (chunkUpdater != null) {
|
||||||
|
chunkUpdater.stop();
|
||||||
|
}
|
||||||
|
|
||||||
chunkUpdater = new ChunkUpdater(world);
|
chunkUpdater = new ChunkUpdater(world);
|
||||||
if (sender().isPlayer()) {
|
if (sender().isPlayer()) {
|
||||||
sender().sendMessage(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
sender().sendMessage(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
||||||
} else {
|
} else {
|
||||||
Iris.info(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
Iris.info(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
||||||
}
|
}
|
||||||
@@ -52,14 +57,7 @@ public class CommandUpdater implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Pause the updater")
|
@Decree(description = "Pause the updater")
|
||||||
public void pause(
|
public void pause( ) {
|
||||||
@Param(description = "World to pause the Updater at")
|
|
||||||
World world
|
|
||||||
) {
|
|
||||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
|
||||||
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (chunkUpdater == null) {
|
if (chunkUpdater == null) {
|
||||||
sender().sendMessage(C.GOLD + "You cant pause something that doesnt exist?");
|
sender().sendMessage(C.GOLD + "You cant pause something that doesnt exist?");
|
||||||
return;
|
return;
|
||||||
@@ -67,40 +65,32 @@ public class CommandUpdater implements DecreeExecutor {
|
|||||||
boolean status = chunkUpdater.pause();
|
boolean status = chunkUpdater.pause();
|
||||||
if (sender().isPlayer()) {
|
if (sender().isPlayer()) {
|
||||||
if (status) {
|
if (status) {
|
||||||
sender().sendMessage(C.IRIS + "Paused task for: " + C.GRAY + world.getName());
|
sender().sendMessage(C.IRIS + "Paused task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
} else {
|
} else {
|
||||||
sender().sendMessage(C.IRIS + "Unpause task for: " + C.GRAY + world.getName());
|
sender().sendMessage(C.IRIS + "Unpause task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (status) {
|
if (status) {
|
||||||
Iris.info(C.IRIS + "Paused task for: " + C.GRAY + world.getName());
|
Iris.info(C.IRIS + "Paused task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
} else {
|
} else {
|
||||||
Iris.info(C.IRIS + "Unpause task for: " + C.GRAY + world.getName());
|
Iris.info(C.IRIS + "Unpause task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Stops the updater")
|
@Decree(description = "Stops the updater")
|
||||||
public void stop(
|
public void stop() {
|
||||||
@Param(description = "World to stop the Updater at")
|
|
||||||
World world
|
|
||||||
) {
|
|
||||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
|
||||||
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (chunkUpdater == null) {
|
if (chunkUpdater == null) {
|
||||||
sender().sendMessage(C.GOLD + "You cant stop something that doesnt exist?");
|
sender().sendMessage(C.GOLD + "You cant stop something that doesnt exist?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sender().isPlayer()) {
|
if (sender().isPlayer()) {
|
||||||
sender().sendMessage("Stopping Updater for: " + C.GRAY + world.getName());
|
sender().sendMessage("Stopping Updater for: " + C.GRAY + chunkUpdater.getName());
|
||||||
} else {
|
} else {
|
||||||
Iris.info("Stopping Updater for: " + C.GRAY + world.getName());
|
Iris.info("Stopping Updater for: " + C.GRAY + chunkUpdater.getName());
|
||||||
}
|
}
|
||||||
chunkUpdater.stop();
|
chunkUpdater.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.edit.BlockSignal;
|
import com.volmit.iris.core.edit.BlockSignal;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
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.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisRegion;
|
import com.volmit.iris.engine.object.IrisRegion;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
@@ -38,6 +39,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Decree(name = "what", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris What?")
|
@Decree(name = "what", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris What?")
|
||||||
@@ -86,7 +88,8 @@ public class CommandWhat implements DecreeExecutor {
|
|||||||
@Decree(description = "What region am i in?", origin = DecreeOrigin.PLAYER)
|
@Decree(description = "What region am i in?", origin = DecreeOrigin.PLAYER)
|
||||||
public void region() {
|
public void region() {
|
||||||
try {
|
try {
|
||||||
IrisRegion r = engine().getRegion(player().getLocation());
|
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
|
||||||
|
IrisRegion r = engine().getRegion(chunk);
|
||||||
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package com.volmit.iris.core.events;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.InventorySlotType;
|
||||||
|
import com.volmit.iris.engine.object.IrisLootTable;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.world.LootGenerateEvent;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.loot.LootContext;
|
||||||
|
import org.bukkit.loot.LootTable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class IrisLootEvent extends Event {
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private static final LootTable EMPTY = new LootTable() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return new NamespacedKey(Iris.instance, "empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<ItemStack> populateLoot(@Nullable Random random, @NotNull LootContext context) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillInventory(@NotNull Inventory inventory, @Nullable Random random, @NotNull LootContext context) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Engine engine;
|
||||||
|
private final Block block;
|
||||||
|
private final InventorySlotType slot;
|
||||||
|
private final KList<IrisLootTable> tables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for IrisLootEvent with mode selection.
|
||||||
|
*
|
||||||
|
* @param engine The engine instance.
|
||||||
|
* @param block The block associated with the event.
|
||||||
|
* @param slot The inventory slot type.
|
||||||
|
* @param tables The list of IrisLootTables. (mutable*)
|
||||||
|
*/
|
||||||
|
public IrisLootEvent(Engine engine, Block block, InventorySlotType slot, KList<IrisLootTable> tables) {
|
||||||
|
this.engine = engine;
|
||||||
|
this.block = block;
|
||||||
|
this.slot = slot;
|
||||||
|
this.tables = tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required method to get the HandlerList for this event.
|
||||||
|
*
|
||||||
|
* @return The HandlerList.
|
||||||
|
*/
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the corresponding Bukkit loot event.
|
||||||
|
* This method integrates your custom IrisLootTables with Bukkit's LootGenerateEvent,
|
||||||
|
* allowing other plugins to modify or cancel the loot generation.
|
||||||
|
*
|
||||||
|
* @return true when the event was canceled
|
||||||
|
*/
|
||||||
|
public static boolean callLootEvent(KList<ItemStack> loot, Inventory inv, World world, int x, int y, int z) {
|
||||||
|
InventoryHolder holder = inv.getHolder();
|
||||||
|
Location loc = new Location(world, x, y, z);
|
||||||
|
if (holder == null) {
|
||||||
|
holder = new InventoryHolder() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Inventory getInventory() {
|
||||||
|
return inv;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
LootContext context = new LootContext.Builder(loc).build();
|
||||||
|
LootGenerateEvent event = new LootGenerateEvent(world, null, holder, EMPTY, context, loot, true);
|
||||||
|
if (!Bukkit.isPrimaryThread()) {
|
||||||
|
Iris.warn("LootGenerateEvent was not called on the main thread, please report this issue.");
|
||||||
|
Thread.dumpStack();
|
||||||
|
J.sfut(() -> Bukkit.getPluginManager().callEvent(event)).join();
|
||||||
|
} else Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
return event.isCancelled();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -276,9 +276,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
//Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
//Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
||||||
//Color color = colorMode ? Color.getHSBColor((float) (n), (float) (n * n * n * n * n * n), (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
Color color = colorMode ? Color.getHSBColor((float) (0.666f - n * 0.666f), 1f, (float) (1f - n * 0.8f)) : Color.getHSBColor(0f, 0f, (float) n);
|
||||||
Color color = colorMode ? Color.getHSBColor((float) n, (float) (n * n * n * n * n * n), (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
|
||||||
|
|
||||||
int rgb = color.getRGB();
|
int rgb = color.getRGB();
|
||||||
img.setRGB(xx, z, rgb);
|
img.setRGB(xx, z, rgb);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,8 +34,6 @@ import com.volmit.iris.util.math.M;
|
|||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -80,12 +78,12 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
this.task = task;
|
this.task = task;
|
||||||
this.pregenerator = new IrisPregenerator(task, method, this);
|
this.pregenerator = new IrisPregenerator(task, method, this);
|
||||||
max = new Position2(0, 0);
|
max = new Position2(0, 0);
|
||||||
min = new Position2(0, 0);
|
min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||||
task.iterateRegions((xx, zz) -> {
|
task.iterateAllChunks((xx, zz) -> {
|
||||||
min.setX(Math.min(xx << 5, min.getX()));
|
min.setX(Math.min(xx, min.getX()));
|
||||||
min.setZ(Math.min(zz << 5, min.getZ()));
|
min.setZ(Math.min(zz, min.getZ()));
|
||||||
max.setX(Math.max((xx << 5) + 31, max.getX()));
|
max.setX(Math.max(xx, max.getX()));
|
||||||
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
max.setZ(Math.max(zz, max.getZ()));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
||||||
@@ -100,7 +98,6 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean shutdownInstance() {
|
public static boolean shutdownInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawRegion(int x, int z, Color color) {
|
public void drawRegion(int x, int z, Color color) {
|
||||||
J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
J.a(() -> task.iterateChunks(x, z, (xx, zz) -> {
|
||||||
draw(xx, zz, color);
|
draw(xx, zz, color);
|
||||||
J.sleep(3);
|
J.sleep(3);
|
||||||
}));
|
}));
|
||||||
@@ -256,27 +253,6 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
public void onRegionGenerated(int x, int z) {
|
public void onRegionGenerated(int x, int z) {
|
||||||
shouldGc();
|
shouldGc();
|
||||||
rgc++;
|
rgc++;
|
||||||
|
|
||||||
// Each region is 32x32 chunks
|
|
||||||
for (int chunkOffsetX = 0; chunkOffsetX < 32; chunkOffsetX++) {
|
|
||||||
for (int chunkOffsetZ = 0; chunkOffsetZ < 32; chunkOffsetZ++) {
|
|
||||||
// Calculate actual chunk coordinates
|
|
||||||
int chunkX = (x << 5) + chunkOffsetX;
|
|
||||||
int chunkZ = (z << 5) + chunkOffsetZ;
|
|
||||||
|
|
||||||
if (engine != null) {
|
|
||||||
// Calculate the center block of the chunk
|
|
||||||
int centerBlockX = (chunkX << 4) + 8;
|
|
||||||
int centerBlockZ = (chunkZ << 4) + 8;
|
|
||||||
|
|
||||||
// Draw the chunk
|
|
||||||
draw(chunkX, chunkZ, engine.draw(centerBlockX, centerBlockZ));
|
|
||||||
} else {
|
|
||||||
// If engine is null, use the default color
|
|
||||||
draw(chunkX, chunkZ, COLOR_GENERATED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shouldGc() {
|
private void shouldGc() {
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
//todo
|
||||||
|
// - Misalignment
|
||||||
|
// - Weird snapping?
|
||||||
public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener {
|
public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener {
|
||||||
private static final long serialVersionUID = 2094606939770332040L;
|
private static final long serialVersionUID = 2094606939770332040L;
|
||||||
private final KList<LivingEntity> lastEntities = new KList<>();
|
private final KList<LivingEntity> lastEntities = new KList<>();
|
||||||
@@ -80,7 +83,6 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener
|
|||||||
private boolean lowtile = false;
|
private boolean lowtile = false;
|
||||||
private boolean follow = false;
|
private boolean follow = false;
|
||||||
private boolean alt = false;
|
private boolean alt = false;
|
||||||
private boolean dragging = false;
|
|
||||||
private IrisRenderer renderer;
|
private IrisRenderer renderer;
|
||||||
private IrisWorld world;
|
private IrisWorld world;
|
||||||
private double velocity = 0;
|
private double velocity = 0;
|
||||||
@@ -202,7 +204,6 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(MouseEvent e) {
|
public void mouseDragged(MouseEvent e) {
|
||||||
dragging = true;
|
|
||||||
Point cp = e.getPoint();
|
Point cp = e.getPoint();
|
||||||
ox += (lx - cp.getX()) * scale;
|
ox += (lx - cp.getX()) * scale;
|
||||||
oz += (lz - cp.getY()) * scale;
|
oz += (lz - cp.getY()) * scale;
|
||||||
@@ -414,8 +415,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private double getWorldX(double screenX) {
|
private double getWorldX(double screenX) {
|
||||||
//return (mscale * screenX) + ((oxp / scale) * mscale);
|
|
||||||
return (mscale * screenX) + ((oxp / scale) * mscale);
|
return (mscale * screenX) + ((oxp / scale) * mscale);
|
||||||
|
// return (mscale * screenX) + ((oxp / scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getWorldZ(double screenZ) {
|
private double getWorldZ(double screenZ) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -55,10 +55,10 @@ public class IrisRenderer {
|
|||||||
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
||||||
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
||||||
Color c;
|
Color c;
|
||||||
if (g.getMax(renderer) <= 0) {
|
if (g.getMax() <= 0) {
|
||||||
// Max is below water level, so it is most likely an ocean biome
|
// Max is below water level, so it is most likely an ocean biome
|
||||||
c = Color.BLUE;
|
c = Color.BLUE;
|
||||||
} else if (g.getMin(renderer) < 0) {
|
} else if (g.getMin() < 0) {
|
||||||
// Min is below water level, but max is not, so it is most likely a shore biome
|
// Min is below water level, but max is not, so it is most likely a shore biome
|
||||||
c = Color.YELLOW;
|
c = Color.YELLOW;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
@@ -27,6 +9,7 @@ import com.willfp.ecoitems.items.EcoItems;
|
|||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
@@ -51,24 +34,27 @@ public class EcoItemsDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
EcoItem item = EcoItems.INSTANCE.getByID(itemId.key());
|
EcoItem item = EcoItems.INSTANCE.getByID(itemId.key());
|
||||||
if (item == null)
|
if (item == null) throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key());
|
||||||
throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key());
|
|
||||||
return itemStack.get(item).clone();
|
return itemStack.get(item).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
return new Identifier[0];
|
return new Identifier[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getItemTypes() {
|
public Identifier[] getItemTypes() {
|
||||||
KList<Identifier> names = new KList<>();
|
KList<Identifier> names = new KList<>();
|
||||||
@@ -85,7 +71,7 @@ public class EcoItemsDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
public boolean isValidProvider(@NotNull Identifier id, boolean isItem) {
|
||||||
return id.namespace().equalsIgnoreCase("ecoitems") && isItem;
|
return id.namespace().equalsIgnoreCase("ecoitems") && isItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.ssomar.score.api.executableitems.ExecutableItemsAPI;
|
import com.ssomar.score.api.executableitems.ExecutableItemsAPI;
|
||||||
@@ -24,6 +6,7 @@ import com.volmit.iris.util.collection.KList;
|
|||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -38,23 +21,27 @@ public class ExecutableItemsDataProvider extends ExternalDataProvider {
|
|||||||
Iris.info("Setting up ExecutableItems Link...");
|
Iris.info("Setting up ExecutableItems Link...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key())
|
return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key())
|
||||||
.map(item -> item.buildItem(1, Optional.empty()))
|
.map(item -> item.buildItem(1, Optional.empty()))
|
||||||
.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()));
|
.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
return new Identifier[0];
|
return new Identifier[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getItemTypes() {
|
public Identifier[] getItemTypes() {
|
||||||
KList<Identifier> names = new KList<>();
|
KList<Identifier> names = new KList<>();
|
||||||
@@ -71,7 +58,7 @@ public class ExecutableItemsDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidProvider(Identifier key, boolean isItem) {
|
public boolean isValidProvider(@NotNull Identifier key, boolean isItem) {
|
||||||
return key.namespace().equalsIgnoreCase("executable_items") && isItem;
|
return key.namespace().equalsIgnoreCase("executable_items") && isItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,29 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public abstract class ExternalDataProvider {
|
public abstract class ExternalDataProvider {
|
||||||
|
|
||||||
@Getter
|
@NonNull
|
||||||
private final String pluginId;
|
private final String pluginId;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Plugin getPlugin() {
|
public Plugin getPlugin() {
|
||||||
return Bukkit.getPluginManager().getPlugin(pluginId);
|
return Bukkit.getPluginManager().getPlugin(pluginId);
|
||||||
}
|
}
|
||||||
@@ -46,24 +34,60 @@ public abstract class ExternalDataProvider {
|
|||||||
|
|
||||||
public abstract void init();
|
public abstract void init();
|
||||||
|
|
||||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
/**
|
||||||
|
* @see ExternalDataProvider#getBlockData(Identifier, KMap)
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public BlockData getBlockData(@NotNull Identifier blockId) throws MissingResourceException {
|
||||||
return getBlockData(blockId, new KMap<>());
|
return getBlockData(blockId, new KMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException;
|
/**
|
||||||
|
* This method returns a {@link BlockData} corresponding to the blockID
|
||||||
|
* it is used in any place Iris accepts {@link BlockData}
|
||||||
|
*
|
||||||
|
* @param blockId The id of the block to get
|
||||||
|
* @param state The state of the block to get
|
||||||
|
* @return Corresponding {@link BlockData} to the blockId
|
||||||
|
* may return {@link IrisCustomData} for blocks that need a world for placement
|
||||||
|
* @throws MissingResourceException when the blockId is invalid
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException;
|
||||||
|
|
||||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
/**
|
||||||
|
* @see ExternalDataProvider#getItemStack(Identifier)
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public ItemStack getItemStack(@NotNull Identifier itemId) throws MissingResourceException {
|
||||||
return getItemStack(itemId, new KMap<>());
|
return getItemStack(itemId, new KMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException;
|
/**
|
||||||
|
* This method returns a {@link ItemStack} corresponding to the itemID
|
||||||
|
* it is used in loot tables
|
||||||
|
*
|
||||||
|
* @param itemId The id of the item to get
|
||||||
|
* @param customNbt Custom nbt to apply to the item
|
||||||
|
* @return Corresponding {@link ItemStack} to the itemId
|
||||||
|
* @throws MissingResourceException when the itemId is invalid
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException;
|
||||||
|
|
||||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
/**
|
||||||
}
|
* This method is used for placing blocks that need to use the plugins api
|
||||||
|
* it will only be called when the {@link ExternalDataProvider#getBlockData(Identifier, KMap)} returned a {@link IrisCustomData}
|
||||||
|
*
|
||||||
|
* @param engine The engine of the world the block is being placed in
|
||||||
|
* @param block The block where the block should be placed
|
||||||
|
* @param blockId The blockId to place
|
||||||
|
*/
|
||||||
|
public void processUpdate(@NotNull Engine engine, @NotNull Block block, @NotNull Identifier blockId) {}
|
||||||
|
|
||||||
public abstract Identifier[] getBlockTypes();
|
public abstract @NotNull Identifier[] getBlockTypes();
|
||||||
|
|
||||||
public abstract Identifier[] getItemTypes();
|
public abstract @NotNull Identifier[] getItemTypes();
|
||||||
|
|
||||||
public abstract boolean isValidProvider(Identifier id, boolean isItem);
|
public abstract boolean isValidProvider(@NotNull Identifier id, boolean isItem);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
@@ -34,124 +16,129 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Leaves;
|
import org.bukkit.block.data.type.Leaves;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class HMCLeavesDataProvider extends ExternalDataProvider {
|
public class HMCLeavesDataProvider extends ExternalDataProvider {
|
||||||
private Object apiInstance;
|
private Object apiInstance;
|
||||||
private WrappedReturningMethod<Object, Material> worldBlockType;
|
private WrappedReturningMethod<Object, Material> worldBlockType;
|
||||||
private WrappedReturningMethod<Object, Boolean> setCustomBlock;
|
private WrappedReturningMethod<Object, Boolean> setCustomBlock;
|
||||||
private Map<String, Object> blockDataMap = Map.of();
|
private Map<String, Object> blockDataMap = Map.of();
|
||||||
private Map<String, Supplier<ItemStack>> itemDataField = Map.of();
|
private Map<String, Supplier<ItemStack>> itemDataField = Map.of();
|
||||||
|
|
||||||
public HMCLeavesDataProvider() {
|
public HMCLeavesDataProvider() {
|
||||||
super("HMCLeaves");
|
super("HMCLeaves");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPluginId() {
|
public String getPluginId() {
|
||||||
return "HMCLeaves";
|
return "HMCLeaves";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
worldBlockType = new WrappedReturningMethod<>((Class<Object>) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType");
|
worldBlockType = new WrappedReturningMethod<>((Class<Object>) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType");
|
||||||
apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI"));
|
apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI"));
|
||||||
setCustomBlock = new WrappedReturningMethod<>((Class<Object>) apiInstance.getClass(), "setCustomBlock", Location.class, String.class, boolean.class);
|
setCustomBlock = new WrappedReturningMethod<>((Class<Object>) apiInstance.getClass(), "setCustomBlock", Location.class, String.class, boolean.class);
|
||||||
Object config = getLeavesConfig(apiInstance.getClass());
|
Object config = getLeavesConfig(apiInstance.getClass());
|
||||||
blockDataMap = getMap(config, "blockDataMap");
|
blockDataMap = getMap(config, "blockDataMap");
|
||||||
itemDataField = getMap(config, "itemSupplierMap");
|
itemDataField = getMap(config, "itemSupplierMap");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("Failed to initialize HMCLeavesDataProvider: " + e.getMessage());
|
Iris.error("Failed to initialize HMCLeavesDataProvider: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
@Override
|
||||||
Object o = blockDataMap.get(blockId.key());
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
if (o == null)
|
Object o = blockDataMap.get(blockId.key());
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
if (o == null)
|
||||||
Material material = worldBlockType.invoke(o, new Object[0]);
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
if (material == null)
|
Material material = worldBlockType.invoke(o, new Object[0]);
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
if (material == null)
|
||||||
BlockData blockData = Bukkit.createBlockData(material);
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
BlockData blockData = Bukkit.createBlockData(material);
|
||||||
leaves.setPersistent(true);
|
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
||||||
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state));
|
leaves.setPersistent(true);
|
||||||
}
|
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
@Override
|
||||||
if (!itemDataField.containsKey(itemId.key()))
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
if (!itemDataField.containsKey(itemId.key()))
|
||||||
return itemDataField.get(itemId.key()).get();
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
}
|
return itemDataField.get(itemId.key()).get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
public void processUpdate(@NotNull Engine engine, @NotNull Block block, @NotNull Identifier blockId) {
|
||||||
var pair = ExternalDataSVC.parseState(blockId);
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
blockId = pair.getA();
|
blockId = pair.getA();
|
||||||
Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false});
|
Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false});
|
||||||
if (result == null || !result)
|
if (result == null || !result)
|
||||||
Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ());
|
Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ());
|
||||||
else if (IrisSettings.get().getGenerator().preventLeafDecay) {
|
else if (IrisSettings.get().getGenerator().preventLeafDecay) {
|
||||||
BlockData blockData = block.getBlockData();
|
BlockData blockData = block.getBlockData();
|
||||||
if (blockData instanceof Leaves leaves)
|
if (blockData instanceof Leaves leaves)
|
||||||
leaves.setPersistent(true);
|
leaves.setPersistent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public Identifier[] getBlockTypes() {
|
@Override
|
||||||
KList<Identifier> names = new KList<>();
|
public Identifier[] getBlockTypes() {
|
||||||
for (String name : blockDataMap.keySet()) {
|
KList<Identifier> names = new KList<>();
|
||||||
try {
|
for (String name : blockDataMap.keySet()) {
|
||||||
Identifier key = new Identifier("hmcleaves", name);
|
try {
|
||||||
if (getBlockData(key) != null)
|
Identifier key = new Identifier("hmcleaves", name);
|
||||||
names.add(key);
|
if (getBlockData(key) != null)
|
||||||
} catch (MissingResourceException ignored) {
|
names.add(key);
|
||||||
}
|
} catch (MissingResourceException ignored) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return names.toArray(new Identifier[0]);
|
return names.toArray(new Identifier[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public Identifier[] getItemTypes() {
|
@Override
|
||||||
KList<Identifier> names = new KList<>();
|
public Identifier[] getItemTypes() {
|
||||||
for (String name : itemDataField.keySet()) {
|
KList<Identifier> names = new KList<>();
|
||||||
try {
|
for (String name : itemDataField.keySet()) {
|
||||||
Identifier key = new Identifier("hmcleaves", name);
|
try {
|
||||||
if (getItemStack(key) != null)
|
Identifier key = new Identifier("hmcleaves", name);
|
||||||
names.add(key);
|
if (getItemStack(key) != null)
|
||||||
} catch (MissingResourceException ignored) {
|
names.add(key);
|
||||||
}
|
} catch (MissingResourceException ignored) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return names.toArray(new Identifier[0]);
|
return names.toArray(new Identifier[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
public boolean isValidProvider(@NotNull Identifier id, boolean isItem) {
|
||||||
return (isItem ? itemDataField.keySet() : blockDataMap.keySet()).contains(id.key());
|
return (isItem ? itemDataField.keySet() : blockDataMap.keySet()).contains(id.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
private <C, T> Map<String, T> getMap(C config, String name) {
|
private <C, T> Map<String, T> getMap(C config, String name) {
|
||||||
WrappedField<C, Map<String, T>> field = new WrappedField<>((Class<C>) config.getClass(), name);
|
WrappedField<C, Map<String, T>> field = new WrappedField<>((Class<C>) config.getClass(), name);
|
||||||
return field.get(config);
|
return field.get(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <A> A getApiInstance(Class<A> apiClass) {
|
private <A> A getApiInstance(Class<A> apiClass) {
|
||||||
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||||
return instance.invoke();
|
return instance.invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private <A, C> C getLeavesConfig(Class<A> apiClass) {
|
private <A, C> C getLeavesConfig(Class<A> apiClass) {
|
||||||
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||||
WrappedField<A, C> config = new WrappedField<>(apiClass, "config");
|
WrappedField<A, C> config = new WrappedField<>(apiClass, "config");
|
||||||
return config.get(instance.invoke());
|
return config.get(instance.invoke());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
@@ -25,6 +7,7 @@ import dev.lone.itemsadder.api.CustomBlock;
|
|||||||
import dev.lone.itemsadder.api.CustomStack;
|
import dev.lone.itemsadder.api.CustomStack;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
@@ -50,13 +33,15 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
return CustomBlock.getBaseBlockData(blockId.toString());
|
return CustomBlock.getBaseBlockData(blockId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
CustomStack stack = CustomStack.getInstance(itemId.toString());
|
CustomStack stack = CustomStack.getInstance(itemId.toString());
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
@@ -64,6 +49,7 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
|
|||||||
return stack.getItemStack();
|
return stack.getItemStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
KList<Identifier> keys = new KList<>();
|
KList<Identifier> keys = new KList<>();
|
||||||
@@ -73,6 +59,7 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
|
|||||||
return keys.toArray(new Identifier[0]);
|
return keys.toArray(new Identifier[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getItemTypes() {
|
public Identifier[] getItemTypes() {
|
||||||
KList<Identifier> keys = new KList<>();
|
KList<Identifier> keys = new KList<>();
|
||||||
@@ -83,7 +70,7 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
public boolean isValidProvider(@NotNull Identifier id, boolean isItem) {
|
||||||
return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace());
|
return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
@@ -29,6 +11,7 @@ import net.Indyuce.mmoitems.api.block.CustomBlock;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@@ -45,21 +28,21 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
|
|||||||
Iris.info("Setting up MMOItems Link...");
|
Iris.info("Setting up MMOItems Link...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
int id = -1;
|
int id = -1;
|
||||||
try {
|
try {
|
||||||
id = Integer.parseInt(blockId.key());
|
id = Integer.parseInt(blockId.key());
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {}
|
||||||
}
|
|
||||||
CustomBlock block = api().getCustomBlocks().getBlock(id);
|
CustomBlock block = api().getCustomBlocks().getBlock(id);
|
||||||
if (block == null)
|
if (block == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
|
||||||
return block.getState().getBlockData();
|
return block.getState().getBlockData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
String[] parts = itemId.namespace().split("_", 2);
|
String[] parts = itemId.namespace().split("_", 2);
|
||||||
if (parts.length != 2)
|
if (parts.length != 2)
|
||||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
@@ -96,13 +79,13 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
|
|||||||
ItemStack item = null;
|
ItemStack item = null;
|
||||||
try {
|
try {
|
||||||
item = future.get();
|
item = future.get();
|
||||||
} catch (InterruptedException | ExecutionException ignored) {
|
} catch (InterruptedException | ExecutionException ignored) {}
|
||||||
}
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
KList<Identifier> names = new KList<>();
|
KList<Identifier> names = new KList<>();
|
||||||
@@ -117,6 +100,7 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
|
|||||||
return names.toArray(new Identifier[0]);
|
return names.toArray(new Identifier[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getItemTypes() {
|
public Identifier[] getItemTypes() {
|
||||||
KList<Identifier> names = new KList<>();
|
KList<Identifier> names = new KList<>();
|
||||||
@@ -145,7 +129,7 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
public boolean isValidProvider(@NotNull Identifier id, boolean isItem) {
|
||||||
return isItem ? id.namespace().split("_", 2).length == 2 : id.namespace().equals("mmoitems");
|
return isItem ? id.namespace().split("_", 2).length == 2 : id.namespace().equals("mmoitems");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import io.lumine.mythic.bukkit.BukkitAdapter;
|
||||||
|
import io.lumine.mythic.bukkit.utils.serialize.Chroma;
|
||||||
|
import io.lumine.mythiccrucible.MythicCrucible;
|
||||||
|
import io.lumine.mythiccrucible.items.CrucibleItem;
|
||||||
|
import io.lumine.mythiccrucible.items.ItemManager;
|
||||||
|
import io.lumine.mythiccrucible.items.blocks.CustomBlockItemContext;
|
||||||
|
import io.lumine.mythiccrucible.items.furniture.FurnitureItemContext;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class MythicCrucibleDataProvider extends ExternalDataProvider {
|
||||||
|
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
public MythicCrucibleDataProvider() {
|
||||||
|
super("MythicCrucible");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up MythicCrucible Link...");
|
||||||
|
try {
|
||||||
|
this.itemManager = MythicCrucible.inst().getItemManager();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("Failed to set up MythicCrucible Link: Unable to fetch MythicCrucible instance!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
|
CrucibleItem crucibleItem = this.itemManager.getItem(blockId.key())
|
||||||
|
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()));
|
||||||
|
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
|
||||||
|
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
|
||||||
|
if (furnitureItemContext != null) {
|
||||||
|
return new IrisCustomData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
||||||
|
} else if (blockItemContext != null) {
|
||||||
|
return blockItemContext.getBlockData();
|
||||||
|
}
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
Optional<CrucibleItem> opt = this.itemManager.getItem(itemId.key());
|
||||||
|
return BukkitAdapter.adapt(opt.orElseThrow(() ->
|
||||||
|
new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()))
|
||||||
|
.getMythicItem()
|
||||||
|
.generateItemStack(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (CrucibleItem item : this.itemManager.getItems()) {
|
||||||
|
if (item.getBlockData() == null) continue;
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("crucible", item.getInternalName());
|
||||||
|
if (getBlockData(key) != null) {
|
||||||
|
Iris.info("getBlockTypes: Block loaded '" + item.getInternalName() + "'");
|
||||||
|
names.add(key);
|
||||||
|
}
|
||||||
|
} catch (MissingResourceException ignored) {}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (CrucibleItem item : this.itemManager.getItems()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("crucible", item.getInternalName());
|
||||||
|
if (getItemStack(key) != null) {
|
||||||
|
Iris.info("getItemTypes: Item loaded '" + item.getInternalName() + "'");
|
||||||
|
names.add(key);
|
||||||
|
}
|
||||||
|
} catch (MissingResourceException ignored) {}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processUpdate(@NotNull Engine engine, @NotNull Block block, @NotNull Identifier blockId) {
|
||||||
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
|
var state = pair.getB();
|
||||||
|
blockId = pair.getA();
|
||||||
|
|
||||||
|
Optional<CrucibleItem> item = itemManager.getItem(blockId.key());
|
||||||
|
if (item.isEmpty()) return;
|
||||||
|
FurnitureItemContext furniture = item.get().getFurnitureData();
|
||||||
|
if (furniture == null) return;
|
||||||
|
|
||||||
|
float yaw = 0;
|
||||||
|
BlockFace face = BlockFace.NORTH;
|
||||||
|
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
|
||||||
|
RNG rng = new RNG(seed);
|
||||||
|
if ("true".equals(state.get("randomYaw"))) {
|
||||||
|
yaw = rng.f(0, 360);
|
||||||
|
} else if (state.containsKey("yaw")) {
|
||||||
|
yaw = Float.parseFloat(state.get("yaw"));
|
||||||
|
}
|
||||||
|
if ("true".equals(state.get("randomFace"))) {
|
||||||
|
BlockFace[] faces = BlockFace.values();
|
||||||
|
face = faces[rng.i(0, faces.length - 1)];
|
||||||
|
} else if (state.containsKey("face")) {
|
||||||
|
face = BlockFace.valueOf(state.get("face").toUpperCase());
|
||||||
|
}
|
||||||
|
if (face == BlockFace.SELF) {
|
||||||
|
face = BlockFace.NORTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeColor type = null;
|
||||||
|
Chroma color = null;
|
||||||
|
try {
|
||||||
|
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
|
||||||
|
} catch (NullPointerException | IllegalArgumentException ignored) {}
|
||||||
|
if (type != null) {
|
||||||
|
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
|
||||||
|
if (biomeColor == null) return;
|
||||||
|
color = Chroma.of(biomeColor.getRGB());
|
||||||
|
}
|
||||||
|
furniture.place(block, face, yaw, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(@NotNull Identifier key, boolean isItem) {
|
||||||
|
return key.namespace().equalsIgnoreCase("crucible");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,6 +26,7 @@ import org.bukkit.plugin.Plugin;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MythicMobsLink {
|
public class MythicMobsLink {
|
||||||
|
|
||||||
@@ -54,6 +55,6 @@ public class MythicMobsLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getMythicMobTypes() {
|
public Collection<String> getMythicMobTypes() {
|
||||||
return isEnabled() ? MythicBukkit.inst().getMobManager().getMobNames() : null;
|
return isEnabled() ? MythicBukkit.inst().getMobManager().getMobNames() : List.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.nexomc.nexo.api.NexoBlocks;
|
||||||
|
import com.nexomc.nexo.api.NexoFurniture;
|
||||||
|
import com.nexomc.nexo.api.NexoItems;
|
||||||
|
import com.nexomc.nexo.items.ItemBuilder;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.entity.ItemDisplay;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class NexoDataProvider extends ExternalDataProvider {
|
||||||
|
private final AtomicBoolean failed = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
public NexoDataProvider() {
|
||||||
|
super("Nexo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(@NotNull Identifier blockId, @NotNull KMap<String, String> state) throws MissingResourceException {
|
||||||
|
if (!NexoItems.exists(blockId.key())) {
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier blockState = ExternalDataSVC.buildState(blockId, state);
|
||||||
|
if (NexoBlocks.isCustomBlock(blockId.key())) {
|
||||||
|
BlockData data = NexoBlocks.blockData(blockId.key());
|
||||||
|
if (data == null)
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
return new IrisCustomData(data, blockState);
|
||||||
|
} else if (NexoFurniture.isFurniture(blockId.key())) {
|
||||||
|
return new IrisCustomData(B.getAir(), blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(@NotNull Identifier itemId, @NotNull KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
ItemBuilder builder = NexoItems.itemFromId(itemId.key());
|
||||||
|
if (builder == null) {
|
||||||
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processUpdate(@NotNull Engine engine, @NotNull Block block, @NotNull Identifier blockId) {
|
||||||
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
|
var state = pair.getB();
|
||||||
|
blockId = pair.getA();
|
||||||
|
|
||||||
|
if (NexoBlocks.isCustomBlock(blockId.key())) {
|
||||||
|
NexoBlocks.place(blockId.key(), block.getLocation());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NexoFurniture.isFurniture(blockId.key()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
float yaw = 0;
|
||||||
|
BlockFace face = BlockFace.NORTH;
|
||||||
|
|
||||||
|
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
|
||||||
|
RNG rng = new RNG(seed);
|
||||||
|
if ("true".equals(state.get("randomYaw"))) {
|
||||||
|
yaw = rng.f(0, 360);
|
||||||
|
} else if (state.containsKey("yaw")) {
|
||||||
|
yaw = Float.parseFloat(state.get("yaw"));
|
||||||
|
}
|
||||||
|
if ("true".equals(state.get("randomFace"))) {
|
||||||
|
BlockFace[] faces = BlockFace.values();
|
||||||
|
face = faces[rng.i(0, faces.length - 1)];
|
||||||
|
} else if (state.containsKey("face")) {
|
||||||
|
face = BlockFace.valueOf(state.get("face").toUpperCase());
|
||||||
|
}
|
||||||
|
if (face == BlockFace.SELF) {
|
||||||
|
face = BlockFace.NORTH;
|
||||||
|
}
|
||||||
|
ItemDisplay display = NexoFurniture.place(blockId.key(), block.getLocation(), yaw, face);
|
||||||
|
if (display == null) return;
|
||||||
|
ItemStack itemStack = display.getItemStack();
|
||||||
|
if (itemStack == null) return;
|
||||||
|
|
||||||
|
BiomeColor type = null;
|
||||||
|
try {
|
||||||
|
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
|
||||||
|
} catch (NullPointerException | IllegalArgumentException ignored) {}
|
||||||
|
|
||||||
|
if (type != null) {
|
||||||
|
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
|
||||||
|
if (biomeColor == null) return;
|
||||||
|
var potionColor = Color.fromARGB(biomeColor.getAlpha(), biomeColor.getRed(), biomeColor.getGreen(), biomeColor.getBlue());
|
||||||
|
if (itemStack.getItemMeta() instanceof PotionMeta meta) {
|
||||||
|
meta.setColor(potionColor);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display.setItemStack(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
return NexoItems.itemNames().stream()
|
||||||
|
.map(i -> new Identifier("nexo", i))
|
||||||
|
.filter(i -> {
|
||||||
|
try {
|
||||||
|
return getBlockData(i) != null;
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toArray(Identifier[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
return NexoItems.itemNames().stream()
|
||||||
|
.map(i -> new Identifier("nexo", i))
|
||||||
|
.filter(i -> {
|
||||||
|
try {
|
||||||
|
return getItemStack(i) != null;
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toArray(Identifier[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(@NotNull Identifier id, boolean isItem) {
|
||||||
|
return "nexo".equalsIgnoreCase(id.namespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return super.isReady() && !failed.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.nms.INMS;
|
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
|
||||||
import com.volmit.iris.core.service.ExternalDataSVC;
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
import com.volmit.iris.util.data.B;
|
|
||||||
import com.volmit.iris.util.data.IrisCustomData;
|
|
||||||
import com.volmit.iris.util.math.RNG;
|
|
||||||
import com.volmit.iris.util.reflect.WrappedField;
|
|
||||||
import io.th0rgal.oraxen.api.OraxenItems;
|
|
||||||
import io.th0rgal.oraxen.items.ItemBuilder;
|
|
||||||
import io.th0rgal.oraxen.mechanics.Mechanic;
|
|
||||||
import io.th0rgal.oraxen.mechanics.MechanicFactory;
|
|
||||||
import io.th0rgal.oraxen.mechanics.MechanicsManager;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureFactory;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
|
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.block.data.MultipleFacing;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.ItemDisplay;
|
|
||||||
import org.bukkit.entity.ItemFrame;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.PotionMeta;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.MissingResourceException;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class OraxenDataProvider extends ExternalDataProvider {
|
|
||||||
|
|
||||||
private static final String FIELD_FACTORIES_MAP = "FACTORIES_BY_MECHANIC_ID";
|
|
||||||
|
|
||||||
private WrappedField<MechanicsManager, Map<String, MechanicFactory>> factories;
|
|
||||||
|
|
||||||
public OraxenDataProvider() {
|
|
||||||
super("Oraxen");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
Iris.info("Setting up Oraxen Link...");
|
|
||||||
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
|
|
||||||
if (this.factories.hasFailed()) {
|
|
||||||
Iris.error("Failed to set up Oraxen Link: Unable to fetch MechanicFactoriesMap!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
|
||||||
MechanicFactory factory = getFactory(blockId);
|
|
||||||
if (factory instanceof NoteBlockMechanicFactory f)
|
|
||||||
return f.createNoteBlockData(blockId.key());
|
|
||||||
else if (factory instanceof BlockMechanicFactory f) {
|
|
||||||
MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM);
|
|
||||||
BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.key())).getCustomVariation());
|
|
||||||
return newBlockData;
|
|
||||||
} else if (factory instanceof StringBlockMechanicFactory f) {
|
|
||||||
return f.createTripwireData(blockId.key());
|
|
||||||
} else if (factory instanceof FurnitureFactory) {
|
|
||||||
return new IrisCustomData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
|
||||||
} else
|
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
|
||||||
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
|
|
||||||
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
|
||||||
var pair = ExternalDataSVC.parseState(blockId);
|
|
||||||
var state = pair.getB();
|
|
||||||
blockId = pair.getA();
|
|
||||||
Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key());
|
|
||||||
if (mechanic instanceof FurnitureMechanic f) {
|
|
||||||
float yaw = 0;
|
|
||||||
BlockFace face = BlockFace.NORTH;
|
|
||||||
|
|
||||||
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
|
|
||||||
RNG rng = new RNG(seed);
|
|
||||||
if ("true".equals(state.get("randomYaw"))) {
|
|
||||||
yaw = rng.f(0, 360);
|
|
||||||
} else if (state.containsKey("yaw")) {
|
|
||||||
yaw = Float.parseFloat(state.get("yaw"));
|
|
||||||
}
|
|
||||||
if ("true".equals(state.get("randomFace"))) {
|
|
||||||
BlockFace[] faces = BlockFace.values();
|
|
||||||
face = faces[rng.i(0, faces.length - 1)];
|
|
||||||
} else if (state.containsKey("face")) {
|
|
||||||
face = BlockFace.valueOf(state.get("face").toUpperCase());
|
|
||||||
}
|
|
||||||
if (face == BlockFace.SELF) {
|
|
||||||
face = BlockFace.NORTH;
|
|
||||||
}
|
|
||||||
ItemStack itemStack = OraxenItems.getItemById(f.getItemID()).build();
|
|
||||||
Entity entity = f.place(block.getLocation(), itemStack, yaw, face, false);
|
|
||||||
|
|
||||||
Consumer<ItemStack> setter = null;
|
|
||||||
if (entity instanceof ItemFrame frame) {
|
|
||||||
itemStack = frame.getItem();
|
|
||||||
setter = frame::setItem;
|
|
||||||
} else if (entity instanceof ItemDisplay display) {
|
|
||||||
itemStack = display.getItemStack();
|
|
||||||
setter = display::setItemStack;
|
|
||||||
}
|
|
||||||
if (setter == null || itemStack == null) return;
|
|
||||||
|
|
||||||
BiomeColor type = null;
|
|
||||||
try {
|
|
||||||
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
|
|
||||||
} catch (NullPointerException | IllegalArgumentException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != null) {
|
|
||||||
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
|
|
||||||
if (biomeColor == null) return;
|
|
||||||
var potionColor = Color.fromARGB(biomeColor.getAlpha(), biomeColor.getRed(), biomeColor.getGreen(), biomeColor.getBlue());
|
|
||||||
if (itemStack.getItemMeta() instanceof PotionMeta meta) {
|
|
||||||
meta.setColor(potionColor);
|
|
||||||
itemStack.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setter.accept(itemStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier[] getBlockTypes() {
|
|
||||||
KList<Identifier> names = new KList<>();
|
|
||||||
for (String name : OraxenItems.getItemNames()) {
|
|
||||||
try {
|
|
||||||
Identifier key = new Identifier("oraxen", name);
|
|
||||||
if (getBlockData(key) != null)
|
|
||||||
names.add(key);
|
|
||||||
} catch (MissingResourceException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return names.toArray(new Identifier[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier[] getItemTypes() {
|
|
||||||
KList<Identifier> names = new KList<>();
|
|
||||||
for (String name : OraxenItems.getItemNames()) {
|
|
||||||
try {
|
|
||||||
Identifier key = new Identifier("oraxen", name);
|
|
||||||
if (getItemStack(key) != null)
|
|
||||||
names.add(key);
|
|
||||||
} catch (MissingResourceException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return names.toArray(new Identifier[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReady() {
|
|
||||||
if (super.isReady()) {
|
|
||||||
if (factories == null) {
|
|
||||||
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
|
|
||||||
}
|
|
||||||
return super.isReady() && !factories.hasFailed();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidProvider(Identifier key, boolean isItem) {
|
|
||||||
return key.namespace().equalsIgnoreCase("oraxen");
|
|
||||||
}
|
|
||||||
|
|
||||||
private MechanicFactory getFactory(Identifier key) throws MissingResourceException {
|
|
||||||
return factories.get().values().stream()
|
|
||||||
.filter(i -> i.getItems().contains(key.key()))
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.namespace(), key.key()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,16 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
|
import com.volmit.iris.util.data.KCache;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WorldEditLink {
|
public class WorldEditLink {
|
||||||
private static final AtomicCache<Boolean> active = new AtomicCache<>();
|
private static final AtomicCache<Boolean> active = new AtomicCache<>();
|
||||||
@@ -46,8 +31,7 @@ public class WorldEditLink {
|
|||||||
Object region = null;
|
Object region = null;
|
||||||
try {
|
try {
|
||||||
region = localSession.getClass().getDeclaredMethod("getSelection", Class.forName("com.sk89q.worldedit.world.World")).invoke(localSession, world);
|
region = localSession.getClass().getDeclaredMethod("getSelection", Class.forName("com.sk89q.worldedit.world.World")).invoke(localSession, world);
|
||||||
} catch (InvocationTargetException ignored) {
|
} catch (InvocationTargetException ignored) {}
|
||||||
}
|
|
||||||
if (region == null) return null;
|
if (region == null) return null;
|
||||||
|
|
||||||
Object min = region.getClass().getDeclaredMethod("getMinimumPoint").invoke(region);
|
Object min = region.getClass().getDeclaredMethod("getMinimumPoint").invoke(region);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -36,6 +36,7 @@ import com.volmit.iris.util.format.C;
|
|||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import com.volmit.iris.util.reflect.OldEnum;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -337,6 +338,15 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
|
|||||||
this.imageLoader = registerLoader(IrisImage.class);
|
this.imageLoader = registerLoader(IrisImage.class);
|
||||||
this.scriptLoader = registerLoader(IrisScript.class);
|
this.scriptLoader = registerLoader(IrisScript.class);
|
||||||
this.matterObjectLoader = registerLoader(IrisMatterObject.class);
|
this.matterObjectLoader = registerLoader(IrisMatterObject.class);
|
||||||
|
if (OldEnum.exists()) {
|
||||||
|
builder.registerTypeAdapterFactory(new TypeAdapterFactory() {
|
||||||
|
@Override
|
||||||
|
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||||
|
return (TypeAdapter<T>) OldEnum.create(type.getRawType());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
gson = builder.create();
|
gson = builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,6 +444,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
|
|||||||
return adapter.read(reader);
|
return adapter.read(reader);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("Failed to read " + typeToken.getRawType().getCanonicalName() + "... faking objects a little to load the file at least.");
|
Iris.error("Failed to read " + typeToken.getRawType().getCanonicalName() + "... faking objects a little to load the file at least.");
|
||||||
|
Iris.reportError(e);
|
||||||
try {
|
try {
|
||||||
return (T) typeToken.getRawType().getConstructor().newInstance();
|
return (T) typeToken.getRawType().getConstructor().newInstance();
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms;
|
|
||||||
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
|
||||||
import com.volmit.iris.server.node.IrisSession;
|
|
||||||
import com.volmit.iris.server.packet.work.ChunkPacket;
|
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public interface IHeadless extends Closeable {
|
|
||||||
|
|
||||||
void setSession(IrisSession session);
|
|
||||||
|
|
||||||
int getLoadedChunks();
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
boolean exists(int x, int z);
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
CompletableFuture<Void> generateRegion(MultiBurst burst, int x, int z, int maxConcurrent, PregenListener listener);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
void generateChunk(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
void addChunk(ChunkPacket packet);
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisSettings;
|
|||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class INMS {
|
public class INMS {
|
||||||
@@ -30,10 +31,20 @@ public class INMS {
|
|||||||
"1.20.5", "v1_20_R4",
|
"1.20.5", "v1_20_R4",
|
||||||
"1.20.6", "v1_20_R4",
|
"1.20.6", "v1_20_R4",
|
||||||
"1.21", "v1_21_R1",
|
"1.21", "v1_21_R1",
|
||||||
"1.21.1", "v1_21_R1"
|
"1.21.1", "v1_21_R1",
|
||||||
|
"1.21.2", "v1_21_R2",
|
||||||
|
"1.21.3", "v1_21_R2",
|
||||||
|
"1.21.4", "v1_21_R3"
|
||||||
);
|
);
|
||||||
|
private static final List<Version> PACKS = List.of(
|
||||||
|
new Version(21, 4, "31020"),
|
||||||
|
new Version(21, 2, "31000"),
|
||||||
|
new Version(20, 1, "3910")
|
||||||
|
);
|
||||||
|
|
||||||
//@done
|
//@done
|
||||||
private static final INMSBinding binding = bind();
|
private static final INMSBinding binding = bind();
|
||||||
|
public static final String OVERWORLD_TAG = getOverworldTag();
|
||||||
|
|
||||||
public static INMSBinding get() {
|
public static INMSBinding get() {
|
||||||
return binding;
|
return binding;
|
||||||
@@ -65,7 +76,7 @@ public class INMS {
|
|||||||
Iris.info("Locating NMS Binding for " + code);
|
Iris.info("Locating NMS Binding for " + code);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = Class.forName("com.volmit.iris.core.nms." + code + ".NMSBinding");
|
Class<?> clazz = Class.forName("com.volmit.iris.core.nms."+code+".NMSBinding");
|
||||||
try {
|
try {
|
||||||
Object b = clazz.getConstructor().newInstance();
|
Object b = clazz.getConstructor().newInstance();
|
||||||
if (b instanceof INMSBinding binding) {
|
if (b instanceof INMSBinding binding) {
|
||||||
@@ -76,9 +87,7 @@ public class INMS {
|
|||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException |
|
} catch (ClassNotFoundException|NoClassDefFoundError classNotFoundException) {}
|
||||||
NoClassDefFoundError classNotFoundException) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info("Craftbukkit " + code + " <-> " + NMSBinding1X.class.getSimpleName() + " Successfully Bound");
|
Iris.info("Craftbukkit " + code + " <-> " + NMSBinding1X.class.getSimpleName() + " Successfully Bound");
|
||||||
Iris.warn("Note: Some features of Iris may not work the same since you are on an unsupported version of Minecraft.");
|
Iris.warn("Note: Some features of Iris may not work the same since you are on an unsupported version of Minecraft.");
|
||||||
@@ -86,4 +95,26 @@ public class INMS {
|
|||||||
|
|
||||||
return new NMSBinding1X();
|
return new NMSBinding1X();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getOverworldTag() {
|
||||||
|
var version = Bukkit.getServer().getBukkitVersion().split("-")[0].split("\\.", 3);
|
||||||
|
int major = 0;
|
||||||
|
int minor = 0;
|
||||||
|
|
||||||
|
if (version.length > 2) {
|
||||||
|
major = Integer.parseInt(version[1]);
|
||||||
|
minor = Integer.parseInt(version[2]);
|
||||||
|
} else if (version.length == 2) {
|
||||||
|
major = Integer.parseInt(version[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var p : PACKS) {
|
||||||
|
if (p.major > major || p.minor > minor)
|
||||||
|
continue;
|
||||||
|
return p.tag;
|
||||||
|
}
|
||||||
|
return "3910";
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Version(int major, int minor, String tag) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,12 +18,11 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
import com.volmit.iris.core.nms.container.IPackRepository;
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
|
||||||
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.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
@@ -33,19 +32,13 @@ import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
|||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Dolphin;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.generator.structure.Structure;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface INMSBinding {
|
public interface INMSBinding {
|
||||||
boolean hasTile(Material material);
|
boolean hasTile(Material material);
|
||||||
@@ -97,7 +90,12 @@ public interface INMSBinding {
|
|||||||
MCABiomeContainer newBiomeContainer(int min, int max);
|
MCABiomeContainer newBiomeContainer(int min, int max);
|
||||||
|
|
||||||
default World createWorld(WorldCreator c) {
|
default World createWorld(WorldCreator c) {
|
||||||
return c.createWorld();
|
if (missingDimensionTypes(true, true, true))
|
||||||
|
throw new IllegalStateException("Missing dimenstion types to create world");
|
||||||
|
|
||||||
|
try (var ignored = injectLevelStems()) {
|
||||||
|
return c.createWorld();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int countCustomBiomes();
|
int countCustomBiomes();
|
||||||
@@ -118,11 +116,6 @@ public interface INMSBinding {
|
|||||||
|
|
||||||
Vector3d getBoundingbox(org.bukkit.entity.EntityType entity);
|
Vector3d getBoundingbox(org.bukkit.entity.EntityType entity);
|
||||||
|
|
||||||
default String getMobCategory(EntityType entityType) {
|
|
||||||
// todo: Update to other versions!
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
||||||
|
|
||||||
Color getBiomeColor(Location location, BiomeColor type);
|
Color getBiomeColor(Location location, BiomeColor type);
|
||||||
@@ -131,30 +124,15 @@ public interface INMSBinding {
|
|||||||
return DataVersion.V1192;
|
return DataVersion.V1192;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean registerDimension(String name, IrisDimension dimension);
|
|
||||||
|
|
||||||
boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace);
|
|
||||||
|
|
||||||
boolean dumpRegistry(File... folders);
|
|
||||||
|
|
||||||
void injectBukkit();
|
|
||||||
|
|
||||||
default IHeadless createHeadless(Engine engine) {
|
|
||||||
throw new IllegalStateException("Headless mode not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
default int getSpawnChunkCount(World world) {
|
default int getSpawnChunkCount(World world) {
|
||||||
return 441;
|
return 441;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPackRepository getPackRepository();
|
|
||||||
|
|
||||||
KList<String> getStructureKeys();
|
KList<String> getStructureKeys();
|
||||||
|
|
||||||
default void reconnectAll() {
|
AutoClosing injectLevelStems();
|
||||||
new ArrayList<>(Bukkit.getOnlinePlayers())
|
|
||||||
.forEach(this::reconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reconnect(Player player);
|
Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end);
|
||||||
|
|
||||||
|
boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.function.NastyRunnable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AutoClosing implements AutoCloseable {
|
||||||
|
private final AtomicBoolean closed = new AtomicBoolean();
|
||||||
|
private final NastyRunnable action;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (closed.getAndSet(true)) return;
|
||||||
|
try {
|
||||||
|
action.run();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.container;
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
public enum BiomeColor {
|
public enum BiomeColor {
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.container;
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.container;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface IPackRepository {
|
|
||||||
void reload();
|
|
||||||
|
|
||||||
void reloadWorldData();
|
|
||||||
|
|
||||||
void setSelected(Collection<String> packs);
|
|
||||||
|
|
||||||
boolean addPack(String packId);
|
|
||||||
|
|
||||||
boolean removePack(String packId);
|
|
||||||
|
|
||||||
Collection<String> getAvailableIds();
|
|
||||||
|
|
||||||
Collection<String> getSelectedIds();
|
|
||||||
|
|
||||||
boolean isAvailable(String packId);
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.container;
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|||||||
@@ -1,26 +1,9 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.datapack;
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
||||||
import com.volmit.iris.core.nms.datapack.v1206.DataFixerV1206;
|
import com.volmit.iris.core.nms.datapack.v1206.DataFixerV1206;
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1213.DataFixerV1213;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -31,7 +14,8 @@ import java.util.function.Supplier;
|
|||||||
@Getter
|
@Getter
|
||||||
public enum DataVersion {
|
public enum DataVersion {
|
||||||
V1192("1.19.2", 10, DataFixerV1192::new),
|
V1192("1.19.2", 10, DataFixerV1192::new),
|
||||||
V1205("1.20.6", 41, DataFixerV1206::new);
|
V1205("1.20.6", 41, DataFixerV1206::new),
|
||||||
|
V1213("1.21.3", 57, DataFixerV1213::new);
|
||||||
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
||||||
@Getter(AccessLevel.NONE)
|
@Getter(AccessLevel.NONE)
|
||||||
private final Supplier<IDataFixer> constructor;
|
private final Supplier<IDataFixer> constructor;
|
||||||
@@ -44,6 +28,10 @@ public enum DataVersion {
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IDataFixer get() {
|
||||||
|
return cache.computeIfAbsent(this, k -> constructor.get());
|
||||||
|
}
|
||||||
|
|
||||||
public static IDataFixer getDefault() {
|
public static IDataFixer getDefault() {
|
||||||
return INMS.get().getDataVersion().get();
|
return INMS.get().getDataVersion().get();
|
||||||
}
|
}
|
||||||
@@ -51,8 +39,4 @@ public enum DataVersion {
|
|||||||
public static DataVersion getLatest() {
|
public static DataVersion getLatest() {
|
||||||
return values()[values().length - 1];
|
return values()[values().length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDataFixer get() {
|
|
||||||
return cache.computeIfAbsent(this, k -> constructor.get());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.datapack;
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisRange;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
public interface IDataFixer {
|
public interface IDataFixer {
|
||||||
|
|
||||||
JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json);
|
default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
JSONObject fixDimension(JSONObject json);
|
JSONObject rawDimension(Dimension dimension);
|
||||||
|
|
||||||
|
default JSONObject createDimension(Dimension dimension, IrisRange height, int logicalHeight) {
|
||||||
|
JSONObject obj = rawDimension(dimension);
|
||||||
|
obj.put("min_y", height.getMin());
|
||||||
|
obj.put("height", height.getMax() - height.getMin());
|
||||||
|
obj.put("logical_height", logicalHeight);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Dimension {
|
||||||
|
OVERRWORLD,
|
||||||
|
NETHER,
|
||||||
|
THE_END
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,81 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.datapack.v1192;
|
package com.volmit.iris.core.nms.datapack.v1192;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class DataFixerV1192 implements IDataFixer {
|
public class DataFixerV1192 implements IDataFixer {
|
||||||
|
|
||||||
@Override
|
private static final Map<Dimension, String> DIMENSIONS = Map.of(
|
||||||
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
Dimension.OVERRWORLD, """
|
||||||
return json;
|
{
|
||||||
}
|
"ambient_light": 0.0,
|
||||||
|
"bed_works": true,
|
||||||
|
"coordinate_scale": 1.0,
|
||||||
|
"effects": "minecraft:overworld",
|
||||||
|
"has_ceiling": false,
|
||||||
|
"has_raids": true,
|
||||||
|
"has_skylight": true,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_overworld",
|
||||||
|
"monster_spawn_block_light_limit": 0,
|
||||||
|
"monster_spawn_light_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_inclusive": 7,
|
||||||
|
"min_inclusive": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"natural": true,
|
||||||
|
"piglin_safe": false,
|
||||||
|
"respawn_anchor_works": false,
|
||||||
|
"ultrawarm": false
|
||||||
|
}""",
|
||||||
|
Dimension.NETHER, """
|
||||||
|
{
|
||||||
|
"ambient_light": 0.1,
|
||||||
|
"bed_works": false,
|
||||||
|
"coordinate_scale": 8.0,
|
||||||
|
"effects": "minecraft:the_nether",
|
||||||
|
"fixed_time": 18000,
|
||||||
|
"has_ceiling": true,
|
||||||
|
"has_raids": false,
|
||||||
|
"has_skylight": false,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_nether",
|
||||||
|
"monster_spawn_block_light_limit": 15,
|
||||||
|
"monster_spawn_light_level": 7,
|
||||||
|
"natural": false,
|
||||||
|
"piglin_safe": true,
|
||||||
|
"respawn_anchor_works": true,
|
||||||
|
"ultrawarm": true
|
||||||
|
}""",
|
||||||
|
Dimension.THE_END, """
|
||||||
|
{
|
||||||
|
"ambient_light": 0.0,
|
||||||
|
"bed_works": false,
|
||||||
|
"coordinate_scale": 1.0,
|
||||||
|
"effects": "minecraft:the_end",
|
||||||
|
"fixed_time": 6000,
|
||||||
|
"has_ceiling": false,
|
||||||
|
"has_raids": true,
|
||||||
|
"has_skylight": false,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_end",
|
||||||
|
"monster_spawn_block_light_limit": 0,
|
||||||
|
"monster_spawn_light_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_inclusive": 7,
|
||||||
|
"min_inclusive": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"natural": false,
|
||||||
|
"piglin_safe": false,
|
||||||
|
"respawn_anchor_works": false,
|
||||||
|
"ultrawarm": false
|
||||||
|
}"""
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixDimension(JSONObject json) {
|
public JSONObject rawDimension(Dimension dimension) {
|
||||||
return json;
|
return new JSONObject(DIMENSIONS.get(dimension));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,6 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.datapack.v1206;
|
package com.volmit.iris.core.nms.datapack.v1206;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
||||||
@@ -28,12 +10,14 @@ import com.volmit.iris.util.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class DataFixerV1206 implements IDataFixer {
|
public class DataFixerV1206 extends DataFixerV1192 {
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
int spawnRarity = biome.getSpawnRarity();
|
int spawnRarity = biome.getSpawnRarity();
|
||||||
if (spawnRarity > 0) {
|
if (spawnRarity > 0) {
|
||||||
json.put("creature_spawn_probability", Math.min(spawnRarity / 20d, 0.9999999));
|
json.put("creature_spawn_probability", Math.min(spawnRarity/20d, 0.9999999));
|
||||||
|
} else {
|
||||||
|
json.remove("creature_spawn_probability");
|
||||||
}
|
}
|
||||||
|
|
||||||
var spawns = biome.getSpawns();
|
var spawns = biome.getSpawns();
|
||||||
@@ -44,10 +28,10 @@ public class DataFixerV1206 implements IDataFixer {
|
|||||||
for (IrisBiomeCustomSpawn i : spawns) {
|
for (IrisBiomeCustomSpawn i : spawns) {
|
||||||
JSONArray g = groups.computeIfAbsent(i.getGroup(), (k) -> new JSONArray());
|
JSONArray g = groups.computeIfAbsent(i.getGroup(), (k) -> new JSONArray());
|
||||||
JSONObject o = new JSONObject();
|
JSONObject o = new JSONObject();
|
||||||
o.put("type", "minecraft:" + i.getType().name().toLowerCase());
|
o.put("type", i.getType().getKey());
|
||||||
o.put("weight", i.getWeight());
|
o.put("weight", i.getWeight());
|
||||||
o.put("minCount", Math.min(i.getMinCount() / 20d, 0));
|
o.put("minCount", i.getMinCount());
|
||||||
o.put("maxCount", Math.min(i.getMaxCount() / 20d, 0.9999999));
|
o.put("maxCount", i.getMaxCount());
|
||||||
g.put(o);
|
g.put(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +45,8 @@ public class DataFixerV1206 implements IDataFixer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixDimension(JSONObject json) {
|
public JSONObject rawDimension(Dimension dimension) {
|
||||||
|
JSONObject json = super.rawDimension(dimension);
|
||||||
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
||||||
return json;
|
return json;
|
||||||
var value = (JSONObject) lightLevel.remove("value");
|
var value = (JSONObject) lightLevel.remove("value");
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack.v1213;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1206.DataFixerV1206;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
public class DataFixerV1213 extends DataFixerV1206 {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
json = super.fixCustomBiome(biome, json);
|
||||||
|
json.put("carvers", new JSONArray());
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,41 +18,30 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms.v1X;
|
package com.volmit.iris.core.nms.v1X;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.INMSBinding;
|
import com.volmit.iris.core.nms.INMSBinding;
|
||||||
|
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
import com.volmit.iris.core.nms.container.BlockPos;
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.nms.container.IPackRepository;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
|
||||||
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.format.C;
|
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.Vector3d;
|
import com.volmit.iris.util.math.Vector3d;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.asm.Advice;
|
|
||||||
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
|
|
||||||
import net.bytebuddy.matcher.ElementMatchers;
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.WorldCreator;
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Dolphin;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.generator.structure.Structure;
|
import org.bukkit.generator.structure.Structure;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.io.File;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
public class NMSBinding1X implements INMSBinding {
|
public class NMSBinding1X implements INMSBinding {
|
||||||
private static final boolean supportsCustomHeight = testCustomHeight();
|
private static final boolean supportsCustomHeight = testCustomHeight();
|
||||||
@@ -117,21 +106,6 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return location.getWorld().spawnEntity(location, type);
|
return location.getWorld().spawnEntity(location, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean registerDimension(String name, IrisDimension dimension) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean dumpRegistry(File... folders) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getBiomeColor(Location location, BiomeColor type) {
|
public Color getBiomeColor(Location location, BiomeColor type) {
|
||||||
return Color.GREEN;
|
return Color.GREEN;
|
||||||
@@ -139,7 +113,7 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KList<String> getStructureKeys() {
|
public KList<String> getStructureKeys() {
|
||||||
var list = Registry.STRUCTURE.stream()
|
var list = StreamSupport.stream(Registry.STRUCTURE.spliterator(), false)
|
||||||
.map(Structure::getKey)
|
.map(Structure::getKey)
|
||||||
.map(NamespacedKey::toString)
|
.map(NamespacedKey::toString)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -147,8 +121,18 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reconnect(Player player) {
|
public AutoClosing injectLevelStems() {
|
||||||
|
return new AutoClosing(() -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
|
||||||
|
return new Pair<>(0, new AutoClosing(() -> {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -266,7 +250,7 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
|
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -274,44 +258,4 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");
|
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectBukkit() {
|
|
||||||
try {
|
|
||||||
Iris.info("Injecting Bukkit");
|
|
||||||
new ByteBuddy()
|
|
||||||
.redefine(WorldCreator.class)
|
|
||||||
.visit(Advice.to(WorldCreatorAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(String.class))))
|
|
||||||
.make()
|
|
||||||
.load(WorldCreator.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
|
|
||||||
Iris.info("Injected Bukkit Successfully!");
|
|
||||||
} catch (Exception e) {
|
|
||||||
Iris.info(C.RED + "Failed to Inject Bukkit!");
|
|
||||||
e.printStackTrace();
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPackRepository getPackRepository() {
|
|
||||||
return new PackRepository1X();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WorldCreatorAdvice {
|
|
||||||
@Advice.OnMethodEnter
|
|
||||||
static void enter(@Advice.Argument(0) String name) {
|
|
||||||
File isIrisWorld = new File(name, "iris");
|
|
||||||
boolean isFromIris = false;
|
|
||||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
|
||||||
for (StackTraceElement stack : stackTrace) {
|
|
||||||
if (stack.getClassName().contains("Iris")) {
|
|
||||||
isFromIris = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isFromIris) {
|
|
||||||
Preconditions.checkArgument(!isIrisWorld.exists(), "Only Iris can load Iris Worlds!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.nms.v1X;
|
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.container.IPackRepository;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class PackRepository1X implements IPackRepository {
|
|
||||||
@Override
|
|
||||||
public void reload() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reloadWorldData() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelected(Collection<String> packs) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addPack(String packId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removePack(String packId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getAvailableIds() {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getSelectedIds() {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable(String packId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,38 +1,26 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
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.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RollingSequence;
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
import com.volmit.iris.util.profile.LoadBalancer;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -40,53 +28,40 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
public class ChunkUpdater {
|
public class ChunkUpdater {
|
||||||
private final RollingSequence chunksPerSecond;
|
private final AtomicBoolean paused = new AtomicBoolean();
|
||||||
private final AtomicInteger worldheightsize;
|
private final AtomicBoolean cancelled = new AtomicBoolean();
|
||||||
private final AtomicInteger worldwidthsize;
|
private final KMap<Long, Pair<Long, AtomicInteger>> lastUse = new KMap<>();
|
||||||
private final AtomicInteger totalChunks;
|
private final RollingSequence chunksPerSecond = new RollingSequence(5);
|
||||||
private final AtomicInteger totalMaxChunks;
|
private final AtomicInteger totalMaxChunks = new AtomicInteger();
|
||||||
private final AtomicInteger totalMcaregions;
|
private final AtomicInteger chunksProcessed = new AtomicInteger();
|
||||||
private final AtomicInteger position;
|
private final AtomicInteger chunksProcessedLast = new AtomicInteger();
|
||||||
private final Object pauseLock;
|
private final AtomicInteger chunksUpdated = new AtomicInteger();
|
||||||
|
private final AtomicBoolean serverEmpty = new AtomicBoolean(true);
|
||||||
|
private final AtomicLong lastCpsTime = new AtomicLong(M.ms());
|
||||||
|
private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * IrisSettings.get().getUpdater().getThreadMultiplier(), 1);
|
||||||
|
private final Semaphore semaphore = new Semaphore(256);
|
||||||
|
private final LoadBalancer loadBalancer = new LoadBalancer(semaphore, 256, IrisSettings.get().getUpdater().emptyMsRange);
|
||||||
|
private final AtomicLong startTime = new AtomicLong();
|
||||||
|
private final Dimensions dimensions;
|
||||||
|
private final PregenTask task;
|
||||||
|
private final ExecutorService executor = Executors.newFixedThreadPool(coreLimit);
|
||||||
|
private final ExecutorService chunkExecutor = Executors.newFixedThreadPool(coreLimit);
|
||||||
|
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
private final CountDownLatch latch;
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final World world;
|
private final World world;
|
||||||
private AtomicBoolean paused;
|
|
||||||
private AtomicBoolean cancelled;
|
|
||||||
private KMap<Chunk, Long> lastUse;
|
|
||||||
private AtomicInteger chunksProcessed;
|
|
||||||
private AtomicInteger chunksUpdated;
|
|
||||||
private AtomicLong startTime;
|
|
||||||
private ExecutorService executor;
|
|
||||||
private ExecutorService chunkExecutor;
|
|
||||||
private ScheduledExecutorService scheduler;
|
|
||||||
private CompletableFuture future;
|
|
||||||
private CountDownLatch latch;
|
|
||||||
|
|
||||||
public ChunkUpdater(World world) {
|
public ChunkUpdater(World world) {
|
||||||
this.engine = IrisToolbelt.access(world).getEngine();
|
this.engine = IrisToolbelt.access(world).getEngine();
|
||||||
this.chunksPerSecond = new RollingSequence(5);
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.lastUse = new KMap();
|
this.dimensions = calculateWorldDimensions(new File(world.getWorldFolder(), "region"));
|
||||||
this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1));
|
this.task = dimensions.task();
|
||||||
this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0));
|
this.totalMaxChunks.set(dimensions.count * 1024);
|
||||||
int m = Math.max(worldheightsize.get(), worldwidthsize.get());
|
|
||||||
this.executor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors() / 3, 1));
|
|
||||||
this.chunkExecutor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors() / 3, 1));
|
|
||||||
this.scheduler = Executors.newScheduledThreadPool(1);
|
|
||||||
this.future = new CompletableFuture<>();
|
|
||||||
this.startTime = new AtomicLong();
|
|
||||||
this.worldheightsize.set(m);
|
|
||||||
this.worldwidthsize.set(m);
|
|
||||||
this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16) * (worldwidthsize.get() / 16));
|
|
||||||
this.chunksProcessed = new AtomicInteger();
|
|
||||||
this.chunksUpdated = new AtomicInteger();
|
|
||||||
this.position = new AtomicInteger(0);
|
|
||||||
this.latch = new CountDownLatch(totalMaxChunks.get());
|
this.latch = new CountDownLatch(totalMaxChunks.get());
|
||||||
this.paused = new AtomicBoolean(false);
|
}
|
||||||
this.pauseLock = new Object();
|
|
||||||
this.cancelled = new AtomicBoolean(false);
|
public String getName() {
|
||||||
this.totalChunks = new AtomicInteger(0);
|
return world.getName();
|
||||||
this.totalMcaregions = new AtomicInteger(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChunks() {
|
public int getChunks() {
|
||||||
@@ -114,7 +89,6 @@ public class ChunkUpdater {
|
|||||||
cancelled.set(true);
|
cancelled.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
Iris.info("Updating..");
|
Iris.info("Updating..");
|
||||||
try {
|
try {
|
||||||
@@ -123,11 +97,11 @@ public class ChunkUpdater {
|
|||||||
try {
|
try {
|
||||||
if (!paused.get()) {
|
if (!paused.get()) {
|
||||||
long eta = computeETA();
|
long eta = computeETA();
|
||||||
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 3000;
|
|
||||||
int processed = chunksProcessed.get();
|
int processed = chunksProcessed.get();
|
||||||
double cps = elapsedSeconds > 0 ? processed / (double) elapsedSeconds : 0;
|
double last = processed - chunksProcessedLast.getAndSet(processed);
|
||||||
|
double cps = last / ((M.ms() - lastCpsTime.getAndSet(M.ms())) / 1000d);
|
||||||
chunksPerSecond.put(cps);
|
chunksPerSecond.put(cps);
|
||||||
double percentage = ((double) chunksProcessed.get() / (double) totalMaxChunks.get()) * 100;
|
double percentage = ((double) processed / (double) totalMaxChunks.get()) * 100;
|
||||||
if (!cancelled.get()) {
|
if (!cancelled.get()) {
|
||||||
Iris.info("Updated: " + Form.f(processed) + " of " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta,
|
Iris.info("Updated: " + Form.f(processed) + " of " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta,
|
||||||
2), percentage);
|
2), percentage);
|
||||||
@@ -137,35 +111,20 @@ public class ChunkUpdater {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}, 0, 3, TimeUnit.SECONDS);
|
}, 0, 3, TimeUnit.SECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(this::unloadChunks, 0, 1, TimeUnit.SECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(() -> {
|
||||||
|
boolean empty = Bukkit.getOnlinePlayers().isEmpty();
|
||||||
|
if (serverEmpty.getAndSet(empty) == empty)
|
||||||
|
return;
|
||||||
|
loadBalancer.setRange(empty ? IrisSettings.get().getUpdater().emptyMsRange : IrisSettings.get().getUpdater().defaultMsRange);
|
||||||
|
}, 0, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
var t = new Thread(() -> {
|
||||||
for (int i = 0; i < totalMaxChunks.get(); i++) {
|
run();
|
||||||
if (paused.get()) {
|
close();
|
||||||
synchronized (pauseLock) {
|
}, "Iris Chunk Updater - " + world.getName());
|
||||||
try {
|
t.setPriority(Thread.MAX_PRIORITY);
|
||||||
pauseLock.wait();
|
t.start();
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Iris.error("Interrupted while waiting for executor: ");
|
|
||||||
e.printStackTrace();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
executor.submit(() -> {
|
|
||||||
if (!cancelled.get()) {
|
|
||||||
processNextChunk();
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).thenRun(() -> {
|
|
||||||
try {
|
|
||||||
latch.await();
|
|
||||||
close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -174,14 +133,16 @@ public class ChunkUpdater {
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
unloadAndSaveAllChunks();
|
loadBalancer.close();
|
||||||
|
semaphore.acquire(256);
|
||||||
|
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
executor.awaitTermination(5, TimeUnit.SECONDS);
|
executor.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
chunkExecutor.shutdown();
|
chunkExecutor.shutdown();
|
||||||
chunkExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
chunkExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
scheduler.shutdownNow();
|
scheduler.shutdownNow();
|
||||||
} catch (Exception ignored) {
|
unloadAndSaveAllChunks();
|
||||||
}
|
} catch (Exception ignored) {}
|
||||||
if (cancelled.get()) {
|
if (cancelled.get()) {
|
||||||
Iris.info("Updated: " + Form.f(chunksUpdated.get()) + " Chunks");
|
Iris.info("Updated: " + Form.f(chunksUpdated.get()) + " Chunks");
|
||||||
Iris.info("Irritated: " + Form.f(chunksProcessed.get()) + " of " + Form.f(totalMaxChunks.get()));
|
Iris.info("Irritated: " + Form.f(chunksProcessed.get()) + " of " + Form.f(totalMaxChunks.get()));
|
||||||
@@ -192,18 +153,72 @@ public class ChunkUpdater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNextChunk() {
|
private void run() {
|
||||||
int pos = position.getAndIncrement();
|
task.iterateRegions((rX, rZ) -> {
|
||||||
int[] coords = getChunk(pos);
|
if (cancelled.get())
|
||||||
if (loadChunksIfGenerated(coords[0], coords[1])) {
|
return;
|
||||||
Chunk c = world.getChunkAt(coords[0], coords[1]);
|
|
||||||
engine.updateChunk(c);
|
while (paused.get()) {
|
||||||
chunksUpdated.incrementAndGet();
|
J.sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
task.iterateChunks(rX, rZ, (x, z) -> {
|
||||||
|
while (paused.get() && !cancelled.get()) {
|
||||||
|
J.sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
semaphore.acquire();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunkExecutor.submit(() -> {
|
||||||
|
try {
|
||||||
|
if (!cancelled.get())
|
||||||
|
processChunk(x, z);
|
||||||
|
} finally {
|
||||||
|
latch.countDown();
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processChunk(int x, int z) {
|
||||||
|
if (!loadChunksIfGenerated(x, z)) {
|
||||||
|
chunksProcessed.getAndIncrement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Chunk c = world.getChunkAt(x, z);
|
||||||
|
engine.getMantle().getMantle().getChunk(c);
|
||||||
|
engine.updateChunk(c);
|
||||||
|
|
||||||
|
for (int xx = -1; xx <= 1; xx++) {
|
||||||
|
for (int zz = -1; zz <= 1; zz++) {
|
||||||
|
var counter = lastUse.get(Cache.key(x + xx, z + zz));
|
||||||
|
if (counter != null) counter.getB().decrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
chunksUpdated.incrementAndGet();
|
||||||
|
chunksProcessed.getAndIncrement();
|
||||||
}
|
}
|
||||||
chunksProcessed.getAndIncrement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean loadChunksIfGenerated(int x, int z) {
|
private boolean loadChunksIfGenerated(int x, int z) {
|
||||||
|
if (engine.getMantle().getMantle().hasFlag(x, z, MantleFlag.ETCHED))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (int dx = -1; dx <= 1; dx++) {
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
for (int dz = -1; dz <= 1; dz++) {
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
if (!PaperLib.isChunkGenerated(world, x + dx, z + dz)) {
|
if (!PaperLib.isChunkGenerated(world, x + dx, z + dz)) {
|
||||||
@@ -213,47 +228,79 @@ public class ChunkUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AtomicBoolean generated = new AtomicBoolean(true);
|
AtomicBoolean generated = new AtomicBoolean(true);
|
||||||
KList<Future<?>> futures = new KList<>(9);
|
CountDownLatch latch = new CountDownLatch(9);
|
||||||
for (int dx = -1; dx <= 1; dx++) {
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
for (int dz = -1; dz <= 1; dz++) {
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
int xx = x + dx;
|
int xx = x + dx;
|
||||||
int zz = z + dz;
|
int zz = z + dz;
|
||||||
futures.add(chunkExecutor.submit(() -> {
|
executor.submit(() -> {
|
||||||
Chunk c;
|
|
||||||
try {
|
try {
|
||||||
c = PaperLib.getChunkAtAsync(world, xx, zz, false).get();
|
Chunk c;
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
generated.set(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!c.isLoaded()) {
|
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
J.s(() -> {
|
|
||||||
c.load(false);
|
|
||||||
latch.countDown();
|
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
latch.await();
|
c = PaperLib.getChunkAtAsync(world, xx, zz, false, true)
|
||||||
} catch (InterruptedException ignored) {
|
.thenApply(chunk -> {
|
||||||
|
if (chunk != null)
|
||||||
|
chunk.addPluginChunkTicket(Iris.instance);
|
||||||
|
return chunk;
|
||||||
|
}).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
generated.set(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c == null) {
|
||||||
|
generated.set(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c.isLoaded()) {
|
||||||
|
var future = J.sfut(() -> c.load(false));
|
||||||
|
if (future != null) future.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PaperLib.isChunkGenerated(c.getWorld(), xx, zz))
|
||||||
|
generated.set(false);
|
||||||
|
|
||||||
|
var pair = lastUse.computeIfAbsent(Cache.key(c), k -> new Pair<>(0L, new AtomicInteger(-1)));
|
||||||
|
pair.setA(M.ms());
|
||||||
|
pair.getB().updateAndGet(i -> i == -1 ? 1 : ++i);
|
||||||
|
} finally {
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
if (!c.isGenerated()) {
|
});
|
||||||
generated.set(false);
|
|
||||||
}
|
|
||||||
lastUse.put(c, M.ms());
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!futures.isEmpty()) {
|
|
||||||
futures.removeIf(Future::isDone);
|
try {
|
||||||
try {
|
latch.await();
|
||||||
Thread.sleep(50);
|
} catch (InterruptedException e) {
|
||||||
} catch (InterruptedException ignored) {
|
Iris.info("Interrupted while waiting for chunks to load");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return generated.get();
|
return generated.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void unloadChunks() {
|
||||||
|
for (var key : new ArrayList<>(lastUse.keySet())) {
|
||||||
|
if (key == null) continue;
|
||||||
|
var pair = lastUse.get(key);
|
||||||
|
if (pair == null) continue;
|
||||||
|
var lastUseTime = pair.getA();
|
||||||
|
var counter = pair.getB();
|
||||||
|
if (lastUseTime == null || counter == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (M.ms() - lastUseTime >= 5000 && counter.get() == 0) {
|
||||||
|
int x = Cache.keyX(key);
|
||||||
|
int z = Cache.keyZ(key);
|
||||||
|
J.s(() -> {
|
||||||
|
world.removePluginChunkTicket(x, z, Iris.instance);
|
||||||
|
world.unloadChunk(x, z);
|
||||||
|
lastUse.remove(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void unloadAndSaveAllChunks() {
|
private void unloadAndSaveAllChunks() {
|
||||||
try {
|
try {
|
||||||
J.sfut(() -> {
|
J.sfut(() -> {
|
||||||
@@ -262,13 +309,7 @@ public class ChunkUpdater {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
unloadChunks();
|
||||||
Long lastUseTime = lastUse.get(i);
|
|
||||||
if (lastUseTime != null && M.ms() - lastUseTime >= 5000) {
|
|
||||||
i.unload();
|
|
||||||
lastUse.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -285,7 +326,7 @@ public class ChunkUpdater {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateWorldDimensions(File regionDir, Integer o) {
|
private Dimensions calculateWorldDimensions(File regionDir) {
|
||||||
File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca"));
|
File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca"));
|
||||||
|
|
||||||
int minX = Integer.MAX_VALUE;
|
int minX = Integer.MAX_VALUE;
|
||||||
@@ -298,40 +339,23 @@ public class ChunkUpdater {
|
|||||||
int x = Integer.parseInt(parts[1]);
|
int x = Integer.parseInt(parts[1]);
|
||||||
int z = Integer.parseInt(parts[2]);
|
int z = Integer.parseInt(parts[2]);
|
||||||
|
|
||||||
if (x < minX) minX = x;
|
minX = Math.min(minX, x);
|
||||||
if (x > maxX) maxX = x;
|
maxX = Math.max(maxX, x);
|
||||||
if (z < minZ) minZ = z;
|
minZ = Math.min(minZ, z);
|
||||||
if (z > maxZ) maxZ = z;
|
maxZ = Math.max(maxZ, z);
|
||||||
}
|
}
|
||||||
|
int oX = minX + ((maxX - minX) / 2);
|
||||||
|
int oZ = minZ + ((maxZ - minZ) / 2);
|
||||||
|
|
||||||
int height = (maxX - minX + 1) * 32 * 16;
|
int height = maxX - minX + 1;
|
||||||
int width = (maxZ - minZ + 1) * 32 * 16;
|
int width = maxZ - minZ + 1;
|
||||||
|
|
||||||
if (o == 1) {
|
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
|
||||||
return height;
|
.radiusZ((int) Math.ceil(width / 2d * 512))
|
||||||
}
|
.radiusX((int) Math.ceil(height / 2d * 512))
|
||||||
if (o == 0) {
|
.center(new Position2(oX, oZ))
|
||||||
return width;
|
.build());
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] getChunk(int position) {
|
private record Dimensions(Position2 min, Position2 max, int count, PregenTask task) { }
|
||||||
int p = -1;
|
|
||||||
AtomicInteger xx = new AtomicInteger();
|
|
||||||
AtomicInteger zz = new AtomicInteger();
|
|
||||||
Spiraler s = new Spiraler(worldheightsize.get() * 2, worldwidthsize.get() * 2, (x, z) -> {
|
|
||||||
xx.set(x);
|
|
||||||
zz.set(z);
|
|
||||||
});
|
|
||||||
|
|
||||||
while (s.hasNext() && p++ < position) {
|
|
||||||
s.next();
|
|
||||||
}
|
|
||||||
int[] coords = new int[2];
|
|
||||||
coords[0] = xx.get();
|
|
||||||
coords[1] = zz.get();
|
|
||||||
|
|
||||||
return coords;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,274 @@
|
|||||||
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
|
import com.volmit.iris.util.math.Spiraler;
|
||||||
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class DeepSearchPregenerator extends Thread implements Listener {
|
||||||
|
@Getter
|
||||||
|
private static DeepSearchPregenerator instance;
|
||||||
|
private final DeepSearchJob job;
|
||||||
|
private final File destination;
|
||||||
|
private final int maxPosition;
|
||||||
|
private World world;
|
||||||
|
private final ChronoLatch latch;
|
||||||
|
private static AtomicInteger foundChunks;
|
||||||
|
private final AtomicInteger foundLast;
|
||||||
|
private final AtomicInteger foundTotalChunks;
|
||||||
|
private final AtomicLong startTime;
|
||||||
|
private final RollingSequence chunksPerSecond;
|
||||||
|
private final RollingSequence chunksPerMinute;
|
||||||
|
private final AtomicInteger chunkCachePos;
|
||||||
|
private final AtomicInteger chunkCacheSize;
|
||||||
|
private int pos;
|
||||||
|
private final AtomicInteger foundCacheLast;
|
||||||
|
private final AtomicInteger foundCache;
|
||||||
|
private LinkedHashMap<Integer, Position2> chunkCache;
|
||||||
|
private KList<Position2> chunkQueue;
|
||||||
|
private final ReentrantLock cacheLock;
|
||||||
|
|
||||||
|
private static final Map<String, DeepSearchJob> jobs = new HashMap<>();
|
||||||
|
|
||||||
|
public DeepSearchPregenerator(DeepSearchJob job, File destination) {
|
||||||
|
this.job = job;
|
||||||
|
this.chunkCacheSize = new AtomicInteger(); // todo
|
||||||
|
this.chunkCachePos = new AtomicInteger(1000);
|
||||||
|
this.foundCacheLast = new AtomicInteger();
|
||||||
|
this.foundCache = new AtomicInteger();
|
||||||
|
this.cacheLock = new ReentrantLock();
|
||||||
|
this.destination = destination;
|
||||||
|
this.chunkCache = new LinkedHashMap<>();
|
||||||
|
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||||
|
}).count();
|
||||||
|
this.world = Bukkit.getWorld(job.getWorld().getUID());
|
||||||
|
this.chunkQueue = new KList<>();
|
||||||
|
this.latch = new ChronoLatch(3000);
|
||||||
|
this.startTime = new AtomicLong(M.ms());
|
||||||
|
this.chunksPerSecond = new RollingSequence(10);
|
||||||
|
this.chunksPerMinute = new RollingSequence(10);
|
||||||
|
foundChunks = new AtomicInteger(0);
|
||||||
|
this.foundLast = new AtomicInteger(0);
|
||||||
|
this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||||
|
|
||||||
|
this.pos = 0;
|
||||||
|
jobs.put(job.getWorld().getName(), job);
|
||||||
|
DeepSearchPregenerator.instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(WorldUnloadEvent e) {
|
||||||
|
if (e.getWorld().equals(world)) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while (!interrupted()) {
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
saveNow();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
DeepSearchJob job = jobs.get(world.getName());
|
||||||
|
// chunkCache(); //todo finish this
|
||||||
|
if (latch.flip() && !job.paused) {
|
||||||
|
if (cacheLock.isLocked()) {
|
||||||
|
Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get());
|
||||||
|
} else {
|
||||||
|
long eta = computeETA();
|
||||||
|
save();
|
||||||
|
int secondGenerated = foundChunks.get() - foundLast.get();
|
||||||
|
foundLast.set(foundChunks.get());
|
||||||
|
secondGenerated = secondGenerated / 3;
|
||||||
|
chunksPerSecond.put(secondGenerated);
|
||||||
|
chunksPerMinute.put(secondGenerated * 60);
|
||||||
|
Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (foundChunks.get() >= foundTotalChunks.get()) {
|
||||||
|
Iris.info("Completed DeepSearch!");
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long computeETA() {
|
||||||
|
return (long) ((foundTotalChunks.get() - foundChunks.get()) / chunksPerSecond.getAverage()) * 1000;
|
||||||
|
// todo broken
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
private void queueSystem(Position2 chunk) {
|
||||||
|
if (chunkQueue.isEmpty()) {
|
||||||
|
for (int limit = 512; limit != 0; limit--) {
|
||||||
|
pos = job.getPosition() + 1;
|
||||||
|
chunkQueue.add(getChunk(pos));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//MCAUtil.read();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findInChunk(World world, int x, int z) throws IOException {
|
||||||
|
int xx = x * 16;
|
||||||
|
int zz = z * 16;
|
||||||
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
int height = engine.getHeight(xx + i, zz + j);
|
||||||
|
if (height > 300) {
|
||||||
|
File found = new File("plugins" + "iris" + "found.txt");
|
||||||
|
FileWriter writer = new FileWriter(found);
|
||||||
|
if (!found.exists()) {
|
||||||
|
found.createNewFile();
|
||||||
|
}
|
||||||
|
IrisBiome biome = engine.getBiome(xx, engine.getHeight(), zz);
|
||||||
|
Iris.info("Found at! " + xx + ", " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||||
|
writer.write("Biome at: X: " + xx + " Z: " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position2 getChunk(int position) {
|
||||||
|
int p = -1;
|
||||||
|
AtomicInteger xx = new AtomicInteger();
|
||||||
|
AtomicInteger zz = new AtomicInteger();
|
||||||
|
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||||
|
xx.set(x);
|
||||||
|
zz.set(z);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (s.hasNext() && p++ < position) {
|
||||||
|
s.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Position2(xx.get(), zz.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
J.a(() -> {
|
||||||
|
try {
|
||||||
|
saveNow();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setPausedDeep(World world) {
|
||||||
|
DeepSearchJob job = jobs.get(world.getName());
|
||||||
|
if (isPausedDeep(world)){
|
||||||
|
job.paused = false;
|
||||||
|
} else {
|
||||||
|
job.paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( job.paused) {
|
||||||
|
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPausedDeep(World world) {
|
||||||
|
DeepSearchJob job = jobs.get(world.getName());
|
||||||
|
return job != null && job.isPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdownInstance(World world) throws IOException {
|
||||||
|
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||||
|
DeepSearchJob job = jobs.get(world.getName());
|
||||||
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
File deepFile = new File(worldDirectory, "DeepSearch.json");
|
||||||
|
|
||||||
|
if (job == null) {
|
||||||
|
Iris.error("No DeepSearch job found for world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!job.isPaused()) {
|
||||||
|
job.setPaused(true);
|
||||||
|
}
|
||||||
|
save();
|
||||||
|
jobs.remove(world.getName());
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (deepFile.exists()){
|
||||||
|
deepFile.delete();
|
||||||
|
J.sleep(1000);
|
||||||
|
}
|
||||||
|
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
||||||
|
}
|
||||||
|
}.runTaskLater(Iris.instance, 20L);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("Failed to shutdown DeepSearch for " + world.getName());
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
saveNow();
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void saveNow() throws IOException {
|
||||||
|
IO.writeAll(this.destination, new Gson().toJson(job));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@lombok.Builder
|
||||||
|
public static class DeepSearchJob {
|
||||||
|
private World world;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
private int radiusBlocks = 5000;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
private int position = 0;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
boolean paused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package com.volmit.iris.core.pregenerator;
|
|
||||||
|
|
||||||
public final class EmptyListener implements PregenListener {
|
|
||||||
public static final PregenListener INSTANCE = new EmptyListener();
|
|
||||||
|
|
||||||
private EmptyListener() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChunkGenerating(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChunkGenerated(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRegionGenerated(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRegionGenerating(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChunkCleaned(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRegionSkipped(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkStarted(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkFailed(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkReclaim(int revert) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkGeneratedChunk(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNetworkDownloaded(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaving() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChunkExistsInRegionGen(int x, int z) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,11 +18,8 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
@@ -31,35 +28,17 @@ import com.volmit.iris.util.mantle.Mantle;
|
|||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RollingSequence;
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
import com.volmit.iris.util.nbt.mca.Chunk;
|
|
||||||
import com.volmit.iris.util.nbt.mca.MCAFile;
|
|
||||||
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
import com.volmit.iris.util.scheduling.Looper;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
|
|
||||||
public class IrisPregenerator {
|
public class IrisPregenerator {
|
||||||
private static AtomicInteger generated;
|
|
||||||
private static AtomicInteger totalChunks;
|
|
||||||
private final String saveFile = "regions.json";
|
|
||||||
private final PregenTask task;
|
private final PregenTask task;
|
||||||
private final PregeneratorMethod generator;
|
private final PregeneratorMethod generator;
|
||||||
private final PregenListener listener;
|
private final PregenListener listener;
|
||||||
@@ -70,21 +49,23 @@ public class IrisPregenerator {
|
|||||||
private final RollingSequence chunksPerMinute;
|
private final RollingSequence chunksPerMinute;
|
||||||
private final RollingSequence regionsPerMinute;
|
private final RollingSequence regionsPerMinute;
|
||||||
private final KList<Integer> chunksPerSecondHistory;
|
private final KList<Integer> chunksPerSecondHistory;
|
||||||
|
private static AtomicInteger generated;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
private final AtomicInteger generatedLastMinute;
|
private final AtomicInteger generatedLastMinute;
|
||||||
|
private static AtomicInteger totalChunks;
|
||||||
private final AtomicLong startTime;
|
private final AtomicLong startTime;
|
||||||
private final ChronoLatch minuteLatch;
|
private final ChronoLatch minuteLatch;
|
||||||
private final AtomicReference<String> currentGeneratorMethod;
|
private final AtomicReference<String> currentGeneratorMethod;
|
||||||
|
private final KSet<Position2> generatedRegions;
|
||||||
private final KSet<Position2> retry;
|
private final KSet<Position2> retry;
|
||||||
private final KSet<Position2> net;
|
private final KSet<Position2> net;
|
||||||
private final ChronoLatch cl;
|
private final ChronoLatch cl;
|
||||||
private final ChronoLatch saveLatch = new ChronoLatch(30000);
|
private final ChronoLatch saveLatch = new ChronoLatch(30000);
|
||||||
private Set<Position2> generatedRegions;
|
|
||||||
|
|
||||||
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
|
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
|
||||||
generatedRegions = ConcurrentHashMap.newKeySet();
|
|
||||||
this.listener = listenify(listener);
|
this.listener = listenify(listener);
|
||||||
cl = new ChronoLatch(5000);
|
cl = new ChronoLatch(5000);
|
||||||
|
generatedRegions = new KSet<>();
|
||||||
this.shutdown = new AtomicBoolean(false);
|
this.shutdown = new AtomicBoolean(false);
|
||||||
this.paused = new AtomicBoolean(false);
|
this.paused = new AtomicBoolean(false);
|
||||||
this.task = task;
|
this.task = task;
|
||||||
@@ -101,11 +82,7 @@ public class IrisPregenerator {
|
|||||||
generatedLast = new AtomicInteger(0);
|
generatedLast = new AtomicInteger(0);
|
||||||
generatedLastMinute = new AtomicInteger(0);
|
generatedLastMinute = new AtomicInteger(0);
|
||||||
totalChunks = new AtomicInteger(0);
|
totalChunks = new AtomicInteger(0);
|
||||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet());
|
||||||
loadCompletedRegions();
|
|
||||||
IrisToolbelt.access(generator.getWorld()).getEngine().saveEngineData();
|
|
||||||
}
|
|
||||||
task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024));
|
|
||||||
startTime = new AtomicLong(M.ms());
|
startTime = new AtomicLong(M.ms());
|
||||||
ticker = new Looper() {
|
ticker = new Looper() {
|
||||||
@Override
|
@Override
|
||||||
@@ -130,7 +107,7 @@ public class IrisPregenerator {
|
|||||||
totalChunks.get() - generated.get(),
|
totalChunks.get() - generated.get(),
|
||||||
eta, M.ms() - startTime.get(), currentGeneratorMethod.get());
|
eta, M.ms() - startTime.get(), currentGeneratorMethod.get());
|
||||||
|
|
||||||
if (cl.flip() && !paused.get()) {
|
if (cl.flip()) {
|
||||||
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
||||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||||
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
||||||
@@ -144,18 +121,12 @@ public class IrisPregenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long computeETA() {
|
private long computeETA() {
|
||||||
long currentTime = M.ms();
|
return (long) (totalChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total?
|
||||||
long elapsedTime = currentTime - startTime.get();
|
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers)
|
||||||
int generatedChunks = generated.get();
|
((totalChunks.get() - generated.get()) * ((double) (M.ms() - startTime.get()) / (double) generated.get())) :
|
||||||
int remainingChunks = totalChunks.get() - generatedChunks;
|
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
|
||||||
|
((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000
|
||||||
if (generatedChunks <= 12_000) {
|
);
|
||||||
// quick
|
|
||||||
return (long) (remainingChunks * ((double) elapsedTime / generatedChunks));
|
|
||||||
} else {
|
|
||||||
//smooth
|
|
||||||
return (long) (remainingChunks / chunksPerSecond.getAverage() * 1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,14 +143,8 @@ public class IrisPregenerator {
|
|||||||
shutdown();
|
shutdown();
|
||||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||||
Iris.info(C.IRIS + "Pregen stopped.");
|
Iris.info(C.IRIS + "Pregen stopped.");
|
||||||
// todo: optimizer just takes too long.
|
|
||||||
// if (totalChunks.get() == generated.get() && task.isOptimizer()) {
|
|
||||||
// Iris.info("Starting World Optimizer..");
|
|
||||||
// ChunkUpdater updater = new ChunkUpdater(generator.getWorld());
|
|
||||||
// updater.start();
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
IrisPackBenchmarking.getInstance().finishedBenchmark(chunksPerSecondHistory);
|
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,50 +162,12 @@ public class IrisPregenerator {
|
|||||||
generator.close();
|
generator.close();
|
||||||
ticker.interrupt();
|
ticker.interrupt();
|
||||||
listener.onClose();
|
listener.onClose();
|
||||||
saveCompletedRegions();
|
|
||||||
Mantle mantle = getMantle();
|
Mantle mantle = getMantle();
|
||||||
if (mantle != null) {
|
if (mantle != null) {
|
||||||
mantle.trim(0, 0);
|
mantle.trim(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getGeneratedRegions() {
|
|
||||||
World world = generator.getWorld();
|
|
||||||
File[] region = new File(world.getWorldFolder(), "region").listFiles();
|
|
||||||
BurstExecutor b = MultiBurst.burst.burst(region.length);
|
|
||||||
b.setMulticore(true);
|
|
||||||
b.queue(() -> {
|
|
||||||
for (File file : region) {
|
|
||||||
try {
|
|
||||||
String regex = "r\\.(\\d+)\\.(-?\\d+)\\.mca";
|
|
||||||
Pattern pattern = Pattern.compile(regex);
|
|
||||||
Matcher matcher = pattern.matcher(file.getName());
|
|
||||||
if (!matcher.find()) continue;
|
|
||||||
int x = Integer.parseInt(matcher.group(1));
|
|
||||||
int z = Integer.parseInt(matcher.group(2));
|
|
||||||
Position2 pos = new Position2(x, z);
|
|
||||||
generatedRegions.add(pos);
|
|
||||||
|
|
||||||
MCAFile mca = MCAUtil.read(file, 0);
|
|
||||||
|
|
||||||
boolean notFull = false;
|
|
||||||
for (int i = 0; i < 1024; i++) {
|
|
||||||
Chunk chunk = mca.getChunk(i);
|
|
||||||
if (chunk == null) {
|
|
||||||
generatedRegions.remove(pos);
|
|
||||||
notFull = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Iris.info("Completed MCA region: " + file.getName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
b.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void visitRegion(int x, int z, boolean regions) {
|
private void visitRegion(int x, int z, boolean regions) {
|
||||||
while (paused.get() && !shutdown.get()) {
|
while (paused.get() && !shutdown.get()) {
|
||||||
J.sleep(50);
|
J.sleep(50);
|
||||||
@@ -254,10 +181,6 @@ public class IrisPregenerator {
|
|||||||
Position2 pos = new Position2(x, z);
|
Position2 pos = new Position2(x, z);
|
||||||
|
|
||||||
if (generatedRegions.contains(pos)) {
|
if (generatedRegions.contains(pos)) {
|
||||||
if (regions) {
|
|
||||||
listener.onRegionGenerated(x, z);
|
|
||||||
generated.addAndGet(1024);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +193,7 @@ public class IrisPregenerator {
|
|||||||
} else if (!regions) {
|
} else if (!regions) {
|
||||||
hit = true;
|
hit = true;
|
||||||
listener.onRegionGenerating(x, z);
|
listener.onRegionGenerating(x, z);
|
||||||
PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
task.iterateChunks(x, z, (xx, zz) -> {
|
||||||
while (paused.get() && !shutdown.get()) {
|
while (paused.get() && !shutdown.get()) {
|
||||||
J.sleep(50);
|
J.sleep(50);
|
||||||
}
|
}
|
||||||
@@ -300,39 +223,6 @@ public class IrisPregenerator {
|
|||||||
generator.supportsRegions(x, z, listener);
|
generator.supportsRegions(x, z, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveCompletedRegions() {
|
|
||||||
if (IrisPackBenchmarking.benchmarkInProgress) return;
|
|
||||||
Gson gson = new Gson();
|
|
||||||
try (Writer writer = new FileWriter(generator.getWorld().getWorldFolder().getPath() + "/" + saveFile)) {
|
|
||||||
gson.toJson(new HashSet<>(generatedRegions), writer);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadCompletedRegions() {
|
|
||||||
if (task.isResetCache()) {
|
|
||||||
File test = new File(generator.getWorld().getWorldFolder().getPath() + "/" + saveFile);
|
|
||||||
if (!test.delete()) {
|
|
||||||
Iris.info(C.RED + "Failed to reset region cache ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Gson gson = new Gson();
|
|
||||||
try (Reader reader = new FileReader(generator.getWorld().getWorldFolder().getPath() + "/" + saveFile)) {
|
|
||||||
Type setType = new TypeToken<HashSet<Position2>>() {
|
|
||||||
}.getType();
|
|
||||||
Set<Position2> loadedSet = gson.fromJson(reader, setType);
|
|
||||||
if (loadedSet != null) {
|
|
||||||
generatedRegions.clear();
|
|
||||||
generatedRegions.addAll(loadedSet);
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
// all fine
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pause() {
|
public void pause() {
|
||||||
paused.set(true);
|
paused.set(true);
|
||||||
}
|
}
|
||||||
@@ -361,8 +251,6 @@ public class IrisPregenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegionGenerated(int x, int z) {
|
public void onRegionGenerated(int x, int z) {
|
||||||
generatedRegions.add(new Position2(x, z));
|
|
||||||
saveCompletedRegions();
|
|
||||||
listener.onRegionGenerated(x, z);
|
listener.onRegionGenerated(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@@ -30,7 +12,6 @@ import com.volmit.iris.util.math.Spiraler;
|
|||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -42,31 +23,32 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class LazyPregenerator extends Thread implements Listener {
|
public class LazyPregenerator extends Thread implements Listener {
|
||||||
private static final Map<String, LazyPregenJob> jobs = new HashMap<>();
|
|
||||||
@Getter
|
@Getter
|
||||||
private static LazyPregenerator instance;
|
private static LazyPregenerator instance;
|
||||||
private static AtomicInteger lazyGeneratedChunks;
|
|
||||||
private final LazyPregenJob job;
|
private final LazyPregenJob job;
|
||||||
private final File destination;
|
private final File destination;
|
||||||
private final int maxPosition;
|
private final int maxPosition;
|
||||||
|
private World world;
|
||||||
private final long rate;
|
private final long rate;
|
||||||
private final ChronoLatch latch;
|
private final ChronoLatch latch;
|
||||||
|
private static AtomicInteger lazyGeneratedChunks;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
private final AtomicInteger lazyTotalChunks;
|
private final AtomicInteger lazyTotalChunks;
|
||||||
private final AtomicLong startTime;
|
private final AtomicLong startTime;
|
||||||
private final RollingSequence chunksPerSecond;
|
private final RollingSequence chunksPerSecond;
|
||||||
private final RollingSequence chunksPerMinute;
|
private final RollingSequence chunksPerMinute;
|
||||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
|
||||||
private World world;
|
private static final Map<String, LazyPregenJob> jobs = new HashMap<>();
|
||||||
|
|
||||||
public LazyPregenerator(LazyPregenJob job, File destination) {
|
public LazyPregenerator(LazyPregenJob job, File destination) {
|
||||||
this.job = job;
|
this.job = job;
|
||||||
@@ -105,26 +87,6 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPausedLazy(World world) {
|
|
||||||
LazyPregenJob job = jobs.get(world.getName());
|
|
||||||
if (isPausedLazy(world)) {
|
|
||||||
job.paused = false;
|
|
||||||
} else {
|
|
||||||
job.paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job.paused) {
|
|
||||||
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
|
||||||
} else {
|
|
||||||
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPausedLazy(World world) {
|
|
||||||
LazyPregenJob job = jobs.get(world.getName());
|
|
||||||
return job != null && job.isPaused();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void on(WorldUnloadEvent e) {
|
public void on(WorldUnloadEvent e) {
|
||||||
if (e.getWorld().equals(world)) {
|
if (e.getWorld().equals(world)) {
|
||||||
@@ -183,6 +145,8 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
// todo broken
|
// todo broken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
private void tickGenerate(Position2 chunk) {
|
private void tickGenerate(Position2 chunk) {
|
||||||
executorService.submit(() -> {
|
executorService.submit(() -> {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@@ -201,8 +165,7 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
latch.await();
|
latch.await();
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {}
|
||||||
}
|
|
||||||
lazyGeneratedChunks.addAndGet(1);
|
lazyGeneratedChunks.addAndGet(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -238,6 +201,26 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setPausedLazy(World world) {
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
if (isPausedLazy(world)){
|
||||||
|
job.paused = false;
|
||||||
|
} else {
|
||||||
|
job.paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( job.paused) {
|
||||||
|
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPausedLazy(World world) {
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
return job != null && job.isPaused();
|
||||||
|
}
|
||||||
|
|
||||||
public void shutdownInstance(World world) throws IOException {
|
public void shutdownInstance(World world) throws IOException {
|
||||||
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||||
LazyPregenJob job = jobs.get(world.getName());
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
@@ -258,7 +241,7 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (lazyFile.exists()) {
|
while (lazyFile.exists()){
|
||||||
lazyFile.delete();
|
lazyFile.delete();
|
||||||
J.sleep(1000);
|
J.sleep(1000);
|
||||||
}
|
}
|
||||||
@@ -280,23 +263,23 @@ public class LazyPregenerator extends Thread implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@lombok.Builder
|
||||||
public static class LazyPregenJob {
|
public static class LazyPregenJob {
|
||||||
@Builder.Default
|
|
||||||
boolean silent = false;
|
|
||||||
@Builder.Default
|
|
||||||
boolean paused = false;
|
|
||||||
private String world;
|
private String world;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int healingPosition = 0;
|
private int healingPosition = 0;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private boolean healing = false;
|
private boolean healing = false;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int chunksPerMinute = 32;
|
private int chunksPerMinute = 32;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int radiusBlocks = 5000;
|
private int radiusBlocks = 5000;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int position = 0;
|
private int position = 0;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
boolean silent = false;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
boolean paused = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,8 +23,6 @@ import com.volmit.iris.util.collection.KMap;
|
|||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.Spiraled;
|
import com.volmit.iris.util.math.Spiraled;
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
import com.volmit.iris.util.math.Spiraler;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -32,23 +30,28 @@ import java.util.Comparator;
|
|||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
|
||||||
public class PregenTask {
|
public class PregenTask {
|
||||||
private static final Position2 ZERO = new Position2(0, 0);
|
private static final Position2 ZERO = new Position2(0, 0);
|
||||||
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
|
|
||||||
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
private final boolean gui = false;
|
||||||
|
@Builder.Default
|
||||||
|
private final Position2 center = new Position2(0, 0);
|
||||||
|
@Builder.Default
|
||||||
|
private final int radiusX = 1;
|
||||||
|
@Builder.Default
|
||||||
|
private final int radiusZ = 1;
|
||||||
|
|
||||||
@Builder.Default
|
private final Bounds bounds = new Bounds();
|
||||||
private boolean resetCache = false;
|
|
||||||
@Builder.Default
|
protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) {
|
||||||
private boolean gui = false;
|
this.gui = gui;
|
||||||
@Builder.Default
|
this.center = new ProxiedPos(center);
|
||||||
private Position2 center = new Position2(0, 0);
|
this.radiusX = radiusX;
|
||||||
@Builder.Default
|
this.radiusZ = radiusZ;
|
||||||
private int width = 1;
|
bounds.update();
|
||||||
@Builder.Default
|
}
|
||||||
private int height = 1;
|
|
||||||
|
|
||||||
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
|
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
|
||||||
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
|
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
|
||||||
@@ -76,29 +79,72 @@ public class PregenTask {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KList<Position2> computeChunkOrder() {
|
public void iterateRegions(Spiraled s) {
|
||||||
Position2 center = new Position2(15, 15);
|
var bound = bounds.region();
|
||||||
KList<Position2> p = new KList<>();
|
new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> {
|
||||||
new Spiraler(33, 33, (x, z) -> {
|
if (bound.check(x, z)) s.on(x, z);
|
||||||
int xx = x + 15;
|
})).setOffset(center.getX() >> 9, center.getZ() >> 9).drain();
|
||||||
int zz = z + 15;
|
|
||||||
if (xx < 0 || xx > 31 || zz < 0 || zz > 31) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.add(new Position2(xx, zz));
|
|
||||||
}).drain();
|
|
||||||
p.sort(Comparator.comparing((i) -> i.distance(center)));
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void iterateRegions(Spiraled s) {
|
public void iterateChunks(int rX, int rZ, Spiraled s) {
|
||||||
new Spiraler(getWidth() * 2, getHeight() * 2, s)
|
var bound = bounds.chunk();
|
||||||
.setOffset(center.getX(), center.getZ()).drain();
|
iterateRegion(rX, rZ, ((x, z) -> {
|
||||||
|
if (bound.check(x, z)) s.on(x, z);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void iterateAllChunks(Spiraled s) {
|
public void iterateAllChunks(Spiraled s) {
|
||||||
new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s))
|
iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s)));
|
||||||
.setOffset(center.getX(), center.getZ()).drain();
|
}
|
||||||
|
|
||||||
|
private class Bounds {
|
||||||
|
private Bound chunk = null;
|
||||||
|
private Bound region = null;
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
int maxX = center.getX() + radiusX;
|
||||||
|
int maxZ = center.getZ() + radiusZ;
|
||||||
|
int minX = center.getX() - radiusX;
|
||||||
|
int minZ = center.getZ() - radiusZ;
|
||||||
|
|
||||||
|
chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16));
|
||||||
|
region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bound chunk() {
|
||||||
|
if (chunk == null) update();
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bound region() {
|
||||||
|
if (region == null) update();
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) {
|
||||||
|
private Bound(int minX, int minZ, int maxX, int maxZ) {
|
||||||
|
this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean check(int x, int z) {
|
||||||
|
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ProxiedPos extends Position2 {
|
||||||
|
public ProxiedPos(Position2 p) {
|
||||||
|
super(p.getX(), p.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setX(int x) {
|
||||||
|
throw new IllegalStateException("This Position2 may not be modified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setZ(int z) {
|
||||||
|
throw new IllegalStateException("This Position2 may not be modified");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
package com.volmit.iris.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents something that is capable of generating in chunks or regions, or both
|
* Represents something that is capable of generating in chunks or regions, or both
|
||||||
@@ -78,6 +77,4 @@ public interface PregeneratorMethod {
|
|||||||
void generateChunk(int x, int z, PregenListener listener);
|
void generateChunk(int x, int z, PregenListener listener);
|
||||||
|
|
||||||
Mantle getMantle();
|
Mantle getMantle();
|
||||||
|
|
||||||
World getWorld();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,8 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
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;
|
||||||
@@ -35,24 +18,22 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
|
|||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.apache.logging.log4j.core.util.ExecutorServices;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.WorldUnloadEvent;
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.checkerframework.checker.units.qual.N;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.lang.reflect.Array;
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@@ -60,14 +41,14 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class TurboPregenerator extends Thread implements Listener {
|
public class TurboPregenerator extends Thread implements Listener {
|
||||||
private static final Map<String, TurboPregenJob> jobs = new HashMap<>();
|
|
||||||
@Getter
|
@Getter
|
||||||
private static TurboPregenerator instance;
|
private static TurboPregenerator instance;
|
||||||
private static AtomicInteger turboGeneratedChunks;
|
|
||||||
private final TurboPregenJob job;
|
private final TurboPregenJob job;
|
||||||
private final File destination;
|
private final File destination;
|
||||||
private final int maxPosition;
|
private final int maxPosition;
|
||||||
|
private World world;
|
||||||
private final ChronoLatch latch;
|
private final ChronoLatch latch;
|
||||||
|
private static AtomicInteger turboGeneratedChunks;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
private final AtomicLong cachedLast;
|
private final AtomicLong cachedLast;
|
||||||
private final RollingSequence cachePerSecond;
|
private final RollingSequence cachePerSecond;
|
||||||
@@ -75,15 +56,14 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
private final AtomicLong startTime;
|
private final AtomicLong startTime;
|
||||||
private final RollingSequence chunksPerSecond;
|
private final RollingSequence chunksPerSecond;
|
||||||
private final RollingSequence chunksPerMinute;
|
private final RollingSequence chunksPerMinute;
|
||||||
private final HyperLock hyperLock;
|
|
||||||
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
|
|
||||||
private World world;
|
|
||||||
private KList<Position2> queue;
|
private KList<Position2> queue;
|
||||||
private ConcurrentHashMap<Integer, Position2> cache;
|
private ConcurrentHashMap<Integer, Position2> cache;
|
||||||
private AtomicInteger maxWaiting;
|
private AtomicInteger maxWaiting;
|
||||||
private ReentrantLock cachinglock;
|
private ReentrantLock cachinglock;
|
||||||
private AtomicBoolean caching;
|
private AtomicBoolean caching;
|
||||||
|
private final HyperLock hyperLock;
|
||||||
private MultiBurst burst;
|
private MultiBurst burst;
|
||||||
|
private static final Map<String, TurboPregenJob> jobs = new HashMap<>();
|
||||||
|
|
||||||
public TurboPregenerator(TurboPregenJob job, File destination) {
|
public TurboPregenerator(TurboPregenJob job, File destination) {
|
||||||
this.job = job;
|
this.job = job;
|
||||||
@@ -130,26 +110,6 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPausedTurbo(World world) {
|
|
||||||
TurboPregenJob job = jobs.get(world.getName());
|
|
||||||
if (isPausedTurbo(world)) {
|
|
||||||
job.paused = false;
|
|
||||||
} else {
|
|
||||||
job.paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job.paused) {
|
|
||||||
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
|
||||||
} else {
|
|
||||||
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPausedTurbo(World world) {
|
|
||||||
TurboPregenJob job = jobs.get(world.getName());
|
|
||||||
return job != null && job.isPaused();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void on(WorldUnloadEvent e) {
|
public void on(WorldUnloadEvent e) {
|
||||||
if (e.getWorld().equals(world)) {
|
if (e.getWorld().equals(world)) {
|
||||||
@@ -263,6 +223,7 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
// todo broken
|
// todo broken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||||
private void tickGenerate(Position2 chunk) {
|
private void tickGenerate(Position2 chunk) {
|
||||||
executorService.submit(() -> {
|
executorService.submit(() -> {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@@ -304,6 +265,26 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setPausedTurbo(World world) {
|
||||||
|
TurboPregenJob job = jobs.get(world.getName());
|
||||||
|
if (isPausedTurbo(world)) {
|
||||||
|
job.paused = false;
|
||||||
|
} else {
|
||||||
|
job.paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (job.paused) {
|
||||||
|
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPausedTurbo(World world) {
|
||||||
|
TurboPregenJob job = jobs.get(world.getName());
|
||||||
|
return job != null && job.isPaused();
|
||||||
|
}
|
||||||
|
|
||||||
public void shutdownInstance(World world) throws IOException {
|
public void shutdownInstance(World world) throws IOException {
|
||||||
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||||
TurboPregenJob job = jobs.get(world.getName());
|
TurboPregenJob job = jobs.get(world.getName());
|
||||||
@@ -346,15 +327,15 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@lombok.Builder
|
||||||
public static class TurboPregenJob {
|
public static class TurboPregenJob {
|
||||||
@Builder.Default
|
|
||||||
boolean paused = false;
|
|
||||||
private String world;
|
private String world;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int radiusBlocks = 5000;
|
private int radiusBlocks = 5000;
|
||||||
@Builder.Default
|
@lombok.Builder.Default
|
||||||
private int position = 0;
|
private int position = 0;
|
||||||
|
@lombok.Builder.Default
|
||||||
|
boolean paused = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,10 +26,8 @@ import org.bukkit.World;
|
|||||||
|
|
||||||
public class AsyncOrMedievalPregenMethod implements PregeneratorMethod {
|
public class AsyncOrMedievalPregenMethod implements PregeneratorMethod {
|
||||||
private final PregeneratorMethod method;
|
private final PregeneratorMethod method;
|
||||||
private final World world;
|
|
||||||
|
|
||||||
public AsyncOrMedievalPregenMethod(World world, int threads) {
|
public AsyncOrMedievalPregenMethod(World world, int threads) {
|
||||||
this.world = world;
|
|
||||||
method = PaperLib.isPaper() ? new AsyncPregenMethod(world, threads) : new MedievalPregenMethod(world);
|
method = PaperLib.isPaper() ? new AsyncPregenMethod(world, threads) : new MedievalPregenMethod(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,9 +70,4 @@ public class AsyncOrMedievalPregenMethod implements PregeneratorMethod {
|
|||||||
public Mantle getMantle() {
|
public Mantle getMantle() {
|
||||||
return method.getMantle();
|
return method.getMantle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
package com.volmit.iris.core.pregenerator.methods;
|
package com.volmit.iris.core.pregenerator.methods;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
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.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
@@ -34,21 +34,24 @@ import org.bukkit.World;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||||
|
private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
|
||||||
private final World world;
|
private final World world;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final KList<Future<?>> future;
|
private final Semaphore semaphore;
|
||||||
private final Map<Chunk, Long> lastUse;
|
private final Map<Chunk, Long> lastUse;
|
||||||
|
|
||||||
public AsyncPregenMethod(World world, int threads) {
|
public AsyncPregenMethod(World world, int threads) {
|
||||||
if (!PaperLib.isPaper()) {
|
if (!PaperLib.isPaper()) {
|
||||||
throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!");
|
throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY);
|
burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY);
|
||||||
future = new KList<>(256);
|
semaphore = new Semaphore(256);
|
||||||
this.lastUse = new KMap<>();
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +65,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||||
Long lastUseTime = lastUse.get(i);
|
Long lastUseTime = lastUse.get(i);
|
||||||
if (lastUseTime != null && M.ms() - lastUseTime >= 10000) {
|
if (!i.isLoaded() || (lastUseTime != null && M.ms() - lastUseTime >= 10000)) {
|
||||||
i.unload();
|
i.unload();
|
||||||
lastUse.remove(i);
|
lastUse.remove(i);
|
||||||
}
|
}
|
||||||
@@ -84,43 +87,15 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
} finally {
|
||||||
}
|
semaphore.release();
|
||||||
|
|
||||||
private void waitForChunksPartial(int maxWaiting) {
|
|
||||||
while (future.size() > maxWaiting) {
|
|
||||||
try {
|
|
||||||
Future<?> i = future.remove(0);
|
|
||||||
|
|
||||||
if (i == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
i.get();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void waitForChunks() {
|
|
||||||
for (Future<?> i : future.copy()) {
|
|
||||||
if (i == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
i.get();
|
|
||||||
future.remove(i);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
|
increaseWorkerThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,14 +105,14 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
waitForChunks();
|
semaphore.acquireUninterruptibly(256);
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
burst.close();
|
burst.close();
|
||||||
|
resetWorkerThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save() {
|
||||||
waitForChunksPartial(256);
|
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,10 +129,12 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
@Override
|
@Override
|
||||||
public void generateChunk(int x, int z, PregenListener listener) {
|
public void generateChunk(int x, int z, PregenListener listener) {
|
||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
if (future.size() > 256) {
|
try {
|
||||||
waitForChunksPartial(256);
|
semaphore.acquire();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
future.add(burst.complete(() -> completeChunk(x, z, listener)));
|
burst.complete(() -> completeChunk(x, z, listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -169,8 +146,43 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
public static void increaseWorkerThreads() {
|
||||||
return world;
|
THREAD_COUNT.updateAndGet(i -> {
|
||||||
|
if (i > 0) return 1;
|
||||||
|
try {
|
||||||
|
var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL");
|
||||||
|
var pool = field.get(null);
|
||||||
|
var threads = ((Thread[]) pool.getClass().getDeclaredMethod("getCoreThreads").invoke(pool)).length;
|
||||||
|
var adjusted = IrisSettings.get().getConcurrency().getWorldGenThreads();
|
||||||
|
if (threads >= adjusted) return 0;
|
||||||
|
|
||||||
|
pool.getClass().getDeclaredMethod("adjustThreadCount", int.class).invoke(pool, adjusted);
|
||||||
|
return threads;
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Failed to increase worker threads");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetWorkerThreads() {
|
||||||
|
THREAD_COUNT.updateAndGet(i -> {
|
||||||
|
if (i == 0) return 0;
|
||||||
|
try {
|
||||||
|
var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL");
|
||||||
|
var pool = field.get(null);
|
||||||
|
var method = pool.getClass().getDeclaredMethod("adjustThreadCount", int.class);
|
||||||
|
method.invoke(pool, i);
|
||||||
|
return 0;
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Failed to reset worker threads");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,7 +21,6 @@ package com.volmit.iris.core.pregenerator.methods;
|
|||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
public class DummyPregenMethod implements PregeneratorMethod {
|
public class DummyPregenMethod implements PregeneratorMethod {
|
||||||
@Override
|
@Override
|
||||||
@@ -63,9 +62,4 @@ public class DummyPregenMethod implements PregeneratorMethod {
|
|||||||
public Mantle getMantle() {
|
public Mantle getMantle() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.pregenerator.methods;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.core.nms.IHeadless;
|
|
||||||
import com.volmit.iris.core.nms.INMS;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
|
|
||||||
public class HeadlessPregenMethod implements PregeneratorMethod {
|
|
||||||
private final Engine engine;
|
|
||||||
private final IHeadless headless;
|
|
||||||
private final Semaphore semaphore;
|
|
||||||
private final int max;
|
|
||||||
private final World world;
|
|
||||||
private final MultiBurst burst;
|
|
||||||
|
|
||||||
public HeadlessPregenMethod(Engine engine) {
|
|
||||||
this.world = engine.getWorld().realWorld();
|
|
||||||
this.max = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism());
|
|
||||||
this.engine = engine;
|
|
||||||
this.headless = INMS.get().createHeadless(engine);
|
|
||||||
burst = new MultiBurst("HeadlessPregen", 8 );
|
|
||||||
this.semaphore = new Semaphore(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
semaphore.acquire(max);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
headless.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to close headless");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
burst.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsRegions(int x, int z, PregenListener listener) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethod(int x, int z) {
|
|
||||||
return "Headless";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateRegion(int x, int z, PregenListener listener) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateChunk(int x, int z, PregenListener listener) {
|
|
||||||
try {
|
|
||||||
semaphore.acquire();
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
semaphore.release();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
burst.complete(() -> {
|
|
||||||
try {
|
|
||||||
listener.onChunkGenerating(x, z);
|
|
||||||
headless.generateChunk(x, z);
|
|
||||||
listener.onChunkGenerated(x, z);
|
|
||||||
} finally {
|
|
||||||
semaphore.release();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mantle getMantle() {
|
|
||||||
return engine.getMantle().getMantle();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -71,9 +71,4 @@ public class HybridPregenMethod implements PregeneratorMethod {
|
|||||||
public Mantle getMantle() {
|
public Mantle getMantle() {
|
||||||
return inWorld.getMantle();
|
return inWorld.getMantle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,6 +28,7 @@ import com.volmit.iris.util.collection.KMap;
|
|||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
@@ -118,7 +119,8 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
futures.add(J.sfut(() -> {
|
futures.add(J.sfut(() -> {
|
||||||
Chunk c = world.getChunkAt(x, z);
|
world.getChunkAt(x, z);
|
||||||
|
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||||
lastUse.put(c, M.ms());
|
lastUse.put(c, M.ms());
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
@@ -133,9 +135,4 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,21 +22,23 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
import com.volmit.iris.core.loader.ResourceLoader;
|
import com.volmit.iris.core.loader.ResourceLoader;
|
||||||
import com.volmit.iris.engine.framework.ListFunction;
|
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
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.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.json.JSONArray;
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import com.volmit.iris.util.reflect.OldEnum;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SchemaBuilder {
|
public class SchemaBuilder {
|
||||||
@@ -44,7 +46,6 @@ public class SchemaBuilder {
|
|||||||
private static final String SYMBOL_TYPE__N = "";
|
private static final String SYMBOL_TYPE__N = "";
|
||||||
private static final JSONArray POTION_TYPES = getPotionTypes();
|
private static final JSONArray POTION_TYPES = getPotionTypes();
|
||||||
private static final JSONArray ENCHANT_TYPES = getEnchantTypes();
|
private static final JSONArray ENCHANT_TYPES = getEnchantTypes();
|
||||||
private static final JSONArray ITEM_TYPES = new JSONArray(B.getItemTypes());
|
|
||||||
private static final JSONArray FONT_TYPES = new JSONArray(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
|
private static final JSONArray FONT_TYPES = new JSONArray(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
|
||||||
private final KMap<String, JSONObject> definitions;
|
private final KMap<String, JSONObject> definitions;
|
||||||
private final Class<?> root;
|
private final Class<?> root;
|
||||||
@@ -262,7 +263,7 @@ public class SchemaBuilder {
|
|||||||
|
|
||||||
if (!definitions.containsKey(key)) {
|
if (!definitions.containsKey(key)) {
|
||||||
JSONObject j = new JSONObject();
|
JSONObject j = new JSONObject();
|
||||||
j.put("enum", ITEM_TYPES);
|
j.put("enum", B.getItemTypes());
|
||||||
definitions.put(key, j);
|
definitions.put(key, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,38 +343,9 @@ public class SchemaBuilder {
|
|||||||
description.add(SYMBOL_TYPE__N + " Must be a valid Potion Effect Type (use ctrl+space for auto complete!)");
|
description.add(SYMBOL_TYPE__N + " Must be a valid Potion Effect Type (use ctrl+space for auto complete!)");
|
||||||
|
|
||||||
} else if (k.getType().isEnum()) {
|
} else if (k.getType().isEnum()) {
|
||||||
fancyType = k.getType().getSimpleName().replaceAll("\\QIris\\E", "");
|
fancyType = addEnum(k.getType(), prop, description, k.getType().getEnumConstants(), o -> ((Enum<?>) o).name());
|
||||||
JSONArray a = new JSONArray();
|
} else if (OldEnum.isOldEnum(k.getType())) {
|
||||||
boolean advanced = k.getType().isAnnotationPresent(Desc.class);
|
fancyType = addEnum(k.getType(), prop, description, OldEnum.values(k.getType()), OldEnum::name);
|
||||||
for (Object gg : k.getType().getEnumConstants()) {
|
|
||||||
if (advanced) {
|
|
||||||
try {
|
|
||||||
JSONObject j = new JSONObject();
|
|
||||||
String name = ((Enum<?>) gg).name();
|
|
||||||
j.put("const", name);
|
|
||||||
Desc dd = k.getType().getField(name).getAnnotation(Desc.class);
|
|
||||||
j.put("description", dd == null ? ("No Description for " + name) : dd.value());
|
|
||||||
a.put(j);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
a.put(((Enum<?>) gg).name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String key = (advanced ? "oneof-" : "") + "enum-" + k.getType().getCanonicalName().replaceAll("\\Q.\\E", "-").toLowerCase();
|
|
||||||
|
|
||||||
if (!definitions.containsKey(key)) {
|
|
||||||
JSONObject j = new JSONObject();
|
|
||||||
j.put(advanced ? "oneOf" : "enum", a);
|
|
||||||
definitions.put(key, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
prop.put("$ref", "#/definitions/" + key);
|
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid " + k.getType().getSimpleName().replaceAll("\\QIris\\E", "") + " (use ctrl+space for auto complete!)");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "object" -> {
|
case "object" -> {
|
||||||
@@ -468,7 +440,7 @@ public class SchemaBuilder {
|
|||||||
|
|
||||||
if (!definitions.containsKey(key)) {
|
if (!definitions.containsKey(key)) {
|
||||||
JSONObject j = new JSONObject();
|
JSONObject j = new JSONObject();
|
||||||
j.put("enum", ITEM_TYPES);
|
j.put("enum", B.getItemTypes());
|
||||||
definitions.put(key, j);
|
definitions.put(key, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,39 +491,9 @@ public class SchemaBuilder {
|
|||||||
prop.put("items", items);
|
prop.put("items", items);
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid Potion Effect Type (use ctrl+space for auto complete!)");
|
description.add(SYMBOL_TYPE__N + " Must be a valid Potion Effect Type (use ctrl+space for auto complete!)");
|
||||||
} else if (t.type().isEnum()) {
|
} else if (t.type().isEnum()) {
|
||||||
fancyType = "List of " + t.type().getSimpleName().replaceAll("\\QIris\\E", "") + "s";
|
fancyType = addEnumList(prop, description, t, t.type().getEnumConstants(), o -> ((Enum<?>) o).name());
|
||||||
JSONArray a = new JSONArray();
|
} else if (OldEnum.isOldEnum(t.type())) {
|
||||||
boolean advanced = t.type().isAnnotationPresent(Desc.class);
|
fancyType = addEnumList(prop, description, t, OldEnum.values(t.type()), OldEnum::name);
|
||||||
for (Object gg : t.type().getEnumConstants()) {
|
|
||||||
if (advanced) {
|
|
||||||
try {
|
|
||||||
JSONObject j = new JSONObject();
|
|
||||||
String name = ((Enum<?>) gg).name();
|
|
||||||
j.put("const", name);
|
|
||||||
Desc dd = t.type().getField(name).getAnnotation(Desc.class);
|
|
||||||
j.put("description", dd == null ? ("No Description for " + name) : dd.value());
|
|
||||||
a.put(j);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
a.put(((Enum<?>) gg).name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String key = (advanced ? "oneof-" : "") + "enum-" + t.type().getCanonicalName().replaceAll("\\Q.\\E", "-").toLowerCase();
|
|
||||||
|
|
||||||
if (!definitions.containsKey(key)) {
|
|
||||||
JSONObject j = new JSONObject();
|
|
||||||
j.put(advanced ? "oneOf" : "enum", a);
|
|
||||||
definitions.put(key, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONObject items = new JSONObject();
|
|
||||||
items.put("$ref", "#/definitions/" + key);
|
|
||||||
prop.put("items", items);
|
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid " + t.type().getSimpleName().replaceAll("\\QIris\\E", "") + " (use ctrl+space for auto complete!)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -584,7 +526,7 @@ public class SchemaBuilder {
|
|||||||
if (value instanceof List) {
|
if (value instanceof List) {
|
||||||
d.add(" ");
|
d.add(" ");
|
||||||
d.add("* Default Value is an empty list");
|
d.add("* Default Value is an empty list");
|
||||||
} else if (!cl.isPrimitive() && !(value instanceof Number) && !(value instanceof String) && !(cl.isEnum())) {
|
} else if (!cl.isPrimitive() && !(value instanceof Number) && !(value instanceof String) && !(cl.isEnum()) && !OldEnum.isOldEnum(cl)) {
|
||||||
d.add(" ");
|
d.add(" ");
|
||||||
d.add("* Default Value is a default object (create this object to see default properties)");
|
d.add("* Default Value is a default object (create this object to see default properties)");
|
||||||
} else {
|
} else {
|
||||||
@@ -630,6 +572,50 @@ public class SchemaBuilder {
|
|||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String addEnumList(JSONObject prop, KList<String> description, ArrayType t, Object[] values, Function<Object, String> function) {
|
||||||
|
JSONObject items = new JSONObject();
|
||||||
|
var s = addEnum(t.type(), items, description, values, function);
|
||||||
|
prop.put("items", items);
|
||||||
|
|
||||||
|
return "List of " + s + "s";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String addEnum(Class<?> type, JSONObject prop, KList<String> description, Object[] values, Function<Object, String> function) {
|
||||||
|
JSONArray a = new JSONArray();
|
||||||
|
boolean advanced = type.isAnnotationPresent(Desc.class);
|
||||||
|
for (Object gg : values) {
|
||||||
|
if (advanced) {
|
||||||
|
try {
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
String name = function.apply(gg);
|
||||||
|
j.put("const", name);
|
||||||
|
Desc dd = type.getField(name).getAnnotation(Desc.class);
|
||||||
|
j.put("description", dd == null ? ("No Description for " + name) : dd.value());
|
||||||
|
a.put(j);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a.put(function.apply(gg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = (advanced ? "oneof-" : "") + "enum-" + type.getCanonicalName().replaceAll("\\Q.\\E", "-").toLowerCase();
|
||||||
|
|
||||||
|
if (!definitions.containsKey(key)) {
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
j.put(advanced ? "oneOf" : "enum", a);
|
||||||
|
definitions.put(key, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.put("$ref", "#/definitions/" + key);
|
||||||
|
description.add(SYMBOL_TYPE__N + " Must be a valid " + type.getSimpleName().replaceAll("\\QIris\\E", "") + " (use ctrl+space for auto complete!)");
|
||||||
|
return type.getSimpleName().replaceAll("\\QIris\\E", "");
|
||||||
|
}
|
||||||
|
|
||||||
private String getType(Class<?> c) {
|
private String getType(Class<?> c) {
|
||||||
if (c.equals(int.class) || c.equals(Integer.class) || c.equals(long.class) || c.equals(Long.class)) {
|
if (c.equals(int.class) || c.equals(Integer.class) || c.equals(long.class) || c.equals(Long.class)) {
|
||||||
return "integer";
|
return "integer";
|
||||||
@@ -643,7 +629,7 @@ public class SchemaBuilder {
|
|||||||
return "boolean";
|
return "boolean";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.equals(String.class) || c.isEnum() || c.equals(Enchantment.class) || c.equals(PotionEffectType.class)) {
|
if (c.equals(String.class) || c.isEnum() || OldEnum.isOldEnum(c) || c.equals(Enchantment.class) || c.equals(PotionEffectType.class)) {
|
||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,89 +1,24 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.safeguard;
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
|
||||||
import com.volmit.iris.core.safeguard.handler.onCommandWarning;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.format.Form;
|
|
||||||
import com.volmit.iris.util.misc.getHardware;
|
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getServer;
|
|
||||||
|
|
||||||
public class IrisSafeguard {
|
public class IrisSafeguard {
|
||||||
public static IrisSafeguard instance;
|
public static boolean unstablemode = false;
|
||||||
public boolean acceptUnstable = false;
|
public static boolean warningmode = false;
|
||||||
public boolean unstablemode = false;
|
public static boolean stablemode = false;
|
||||||
public boolean warningmode = false;
|
|
||||||
public boolean stablemode = false;
|
|
||||||
|
|
||||||
public static void InitializeSafeguard() {
|
public static void IrisSafeguardSystem() {
|
||||||
instance = new IrisSafeguard();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void IrisSafeguardSystem() {
|
|
||||||
acceptUnstable = IrisSettings.get().getSafeguard().ignoreBootMode;
|
|
||||||
getServer().getPluginManager().registerEvents(new onCommandWarning(), Iris.instance);
|
|
||||||
Iris.info("Enabled Iris SafeGuard");
|
Iris.info("Enabled Iris SafeGuard");
|
||||||
ServerBootSFG.BootCheck();
|
ServerBootSFG.BootCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void earlySplash() {
|
public static void earlySplash() {
|
||||||
String padd = Form.repeat(" ", 8);
|
if (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode)
|
||||||
String padd2 = Form.repeat(" ", 4);
|
return;
|
||||||
String[] info = new String[]{"", "", "", "", "", padd2 + C.RED + " Iris", padd2 + C.GRAY + " by " + C.DARK_RED + "Volmit Software", padd2 + C.GRAY + " v" + C.RED + Iris.instance.getDescription().getVersion()};
|
|
||||||
String[] splashunstable = {
|
|
||||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
|
||||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.RED + " .(((()))). ",
|
|
||||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.RED + " .((((((())))))). ",
|
|
||||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.RED + " ((((((((())))))))) " + C.GRAY + " @",
|
|
||||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.RED + " ((((((((-))))))))) " + C.GRAY + " @@",
|
|
||||||
padd + C.GRAY + "@@@&&" + C.RED + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
|
||||||
padd + C.GRAY + "@@" + C.RED + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
|
||||||
padd + C.GRAY + "@" + C.RED + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
|
||||||
padd + C.GRAY + "" + C.RED + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
|
||||||
padd + C.GRAY + "" + C.RED + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
|
||||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < info.length; i++) {
|
Iris.instance.splash();
|
||||||
splashunstable[i] += info[i];
|
|
||||||
}
|
|
||||||
Iris.info("Java: " + Iris.instance.getJava());
|
|
||||||
if (!Iris.instance.getServer().getVersion().contains("Purpur")) {
|
|
||||||
if (Iris.instance.getServer().getVersion().contains("Spigot") && Iris.instance.getServer().getVersion().contains("Bukkit")) {
|
|
||||||
Iris.info(C.RED + " Iris requires paper or above to function properly..");
|
|
||||||
} else {
|
|
||||||
Iris.info(C.YELLOW + "Purpur is recommended to use with iris.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (getHardware.getProcessMemory() < 5999) {
|
|
||||||
Iris.warn("6GB+ Ram is recommended");
|
|
||||||
Iris.warn("Process Memory: " + getHardware.getProcessMemory() + " MB");
|
|
||||||
}
|
|
||||||
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
|
||||||
Iris.info("\n\n " + new KList<>(splashunstable).toString("\n") + "\n");
|
|
||||||
UtilsSFG.splash();
|
UtilsSFG.splash();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,20 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.safeguard;
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class ModesSFG {
|
public class ModesSFG {
|
||||||
public static void selectMode() {
|
public static void selectMode() {
|
||||||
if (IrisSafeguard.instance.unstablemode) {
|
if (IrisSafeguard.unstablemode) {
|
||||||
Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode");
|
Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode");
|
||||||
unstable();
|
unstable();
|
||||||
}
|
}
|
||||||
if (IrisSafeguard.instance.warningmode) {
|
if (IrisSafeguard.warningmode) {
|
||||||
Iris.safeguard(C.GOLD + "Iris is running in Warning Mode");
|
Iris.safeguard(C.GOLD + "Iris is running in Warning Mode");
|
||||||
warning();
|
warning();
|
||||||
}
|
}
|
||||||
if (IrisSafeguard.instance.stablemode) {
|
if (IrisSafeguard.stablemode) {
|
||||||
stable();
|
stable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +27,7 @@ public class ModesSFG {
|
|||||||
|
|
||||||
UtilsSFG.printIncompatibleWarnings();
|
UtilsSFG.printIncompatibleWarnings();
|
||||||
|
|
||||||
if (IrisSafeguard.instance.unstablemode) {
|
if (IrisSafeguard.unstablemode) {
|
||||||
Iris.info("");
|
Iris.info("");
|
||||||
Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||||
Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:");
|
Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:");
|
||||||
@@ -63,7 +44,7 @@ public class ModesSFG {
|
|||||||
Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.");
|
Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.");
|
||||||
Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
|
||||||
if (IrisSettings.get().getSafeguard().ignoreBootMode) {
|
if (IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode) {
|
||||||
Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process.");
|
Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process.");
|
||||||
} else {
|
} else {
|
||||||
Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.");
|
Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.");
|
||||||
@@ -83,7 +64,7 @@ public class ModesSFG {
|
|||||||
|
|
||||||
UtilsSFG.printIncompatibleWarnings();
|
UtilsSFG.printIncompatibleWarnings();
|
||||||
|
|
||||||
if (IrisSafeguard.instance.warningmode) {
|
if (IrisSafeguard.warningmode) {
|
||||||
Iris.info("");
|
Iris.info("");
|
||||||
Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||||
Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:");
|
Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:");
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
public class PerformanceSFG {
|
||||||
|
public static void calculatePerformance() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,12 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.safeguard;
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
|
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -39,32 +21,32 @@ import java.util.Map;
|
|||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
import static com.volmit.iris.Iris.getJavaVersion;
|
import static com.volmit.iris.Iris.getJavaVersion;
|
||||||
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||||
|
|
||||||
public class ServerBootSFG {
|
public class ServerBootSFG {
|
||||||
public static final Map<String, Boolean> incompatibilities = new HashMap<>();
|
public static final Map<String, Boolean> incompatibilities = new HashMap<>();
|
||||||
public static boolean isJDK17 = true;
|
public static boolean isCorrectJDK = true;
|
||||||
public static boolean hasEnoughDiskSpace = true;
|
public static boolean hasEnoughDiskSpace = true;
|
||||||
public static boolean isJRE = false;
|
public static boolean isJRE = false;
|
||||||
public static boolean hasPrivileges = true;
|
public static boolean hasPrivileges = true;
|
||||||
public static boolean unsuportedversion = false;
|
public static boolean unsuportedversion = false;
|
||||||
public static boolean passedserversoftware = true;
|
public static boolean missingDimensionTypes = false;
|
||||||
public static String allIncompatibilities;
|
|
||||||
protected static boolean safeguardPassed;
|
protected static boolean safeguardPassed;
|
||||||
|
public static boolean passedserversoftware = true;
|
||||||
protected static int count;
|
protected static int count;
|
||||||
protected static byte severityLow;
|
protected static byte severityLow;
|
||||||
protected static byte severityMedium;
|
protected static byte severityMedium;
|
||||||
protected static byte severityHigh;
|
protected static byte severityHigh;
|
||||||
|
public static String allIncompatibilities;
|
||||||
|
|
||||||
public static void BootCheck() {
|
public static void BootCheck() {
|
||||||
//todo: Stop fucking locking the server, this bricks unix/linux instances, this could get us booted.
|
|
||||||
|
|
||||||
Iris.info("Checking for possible conflicts..");
|
Iris.info("Checking for possible conflicts..");
|
||||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||||
Plugin[] plugins = pluginManager.getPlugins();
|
Plugin[] plugins = pluginManager.getPlugins();
|
||||||
|
|
||||||
incompatibilities.clear();
|
incompatibilities.clear();
|
||||||
incompatibilities.put("Multiverse-Core", false);
|
incompatibilities.put("Multiverse-Core", false);
|
||||||
// incompatibilities.put("dynmap", false);
|
incompatibilities.put("dynmap", false);
|
||||||
incompatibilities.put("TerraformGenerator", false);
|
incompatibilities.put("TerraformGenerator", false);
|
||||||
incompatibilities.put("Stratos", false);
|
incompatibilities.put("Stratos", false);
|
||||||
|
|
||||||
@@ -106,8 +88,8 @@ public class ServerBootSFG {
|
|||||||
severityHigh++;
|
severityHigh++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!List.of(17, 21).contains(getJavaVersion())) {
|
if (!List.of(21).contains(getJavaVersion())) {
|
||||||
isJDK17 = false;
|
isCorrectJDK = false;
|
||||||
joiner.add("Unsupported Java version");
|
joiner.add("Unsupported Java version");
|
||||||
severityMedium++;
|
severityMedium++;
|
||||||
}
|
}
|
||||||
@@ -124,27 +106,33 @@ public class ServerBootSFG {
|
|||||||
// severityMedium++;
|
// severityMedium++;
|
||||||
// } Some servers dont like this
|
// } Some servers dont like this
|
||||||
|
|
||||||
if (!enoughDiskSpace()) {
|
if (!enoughDiskSpace()){
|
||||||
hasEnoughDiskSpace = false;
|
hasEnoughDiskSpace = false;
|
||||||
joiner.add("Insufficient Disk Space");
|
joiner.add("Insufficient Disk Space");
|
||||||
severityMedium++;
|
severityMedium++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IrisContextInjector.isMissingDimensionTypes()) {
|
||||||
|
missingDimensionTypes = true;
|
||||||
|
joiner.add("Missing Dimension Types");
|
||||||
|
severityHigh++;
|
||||||
|
}
|
||||||
|
|
||||||
allIncompatibilities = joiner.toString();
|
allIncompatibilities = joiner.toString();
|
||||||
|
|
||||||
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
||||||
count = severityHigh + severityMedium + severityLow;
|
count = severityHigh + severityMedium + severityLow;
|
||||||
if (safeguardPassed) {
|
if (safeguardPassed) {
|
||||||
IrisSafeguard.instance.stablemode = true;
|
stablemode = true;
|
||||||
Iris.safeguard("Stable mode has been activated.");
|
Iris.safeguard("Stable mode has been activated.");
|
||||||
}
|
}
|
||||||
if (!safeguardPassed) {
|
if (!safeguardPassed) {
|
||||||
if (severityMedium >= 1 && severityHigh == 0) {
|
if (severityMedium >= 1 && severityHigh == 0) {
|
||||||
IrisSafeguard.instance.warningmode = true;
|
warningmode = true;
|
||||||
Iris.safeguard("Warning mode has been activated.");
|
Iris.safeguard("Warning mode has been activated.");
|
||||||
}
|
}
|
||||||
if (severityHigh >= 1) {
|
if (severityHigh >= 1) {
|
||||||
IrisSafeguard.instance.unstablemode = true;
|
unstablemode = true;
|
||||||
Iris.safeguard("Unstable mode has been activated.");
|
Iris.safeguard("Unstable mode has been activated.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,11 +144,9 @@ public class ServerBootSFG {
|
|||||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
// If the compiler is null, it means this is a JRE environment, not a JDK.
|
// If the compiler is null, it means this is a JRE environment, not a JDK.
|
||||||
return compiler != null;
|
return compiler != null;
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasPrivileges() {
|
public static boolean hasPrivileges() {
|
||||||
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
|
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
|
||||||
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
|
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
|
||||||
@@ -176,7 +162,7 @@ public class ServerBootSFG {
|
|||||||
public static boolean enoughDiskSpace() {
|
public static boolean enoughDiskSpace() {
|
||||||
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||||
double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0);
|
double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0);
|
||||||
if (gigabytes > 3) {
|
if (gigabytes > 3){
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.safeguard;
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
@@ -32,10 +14,10 @@ public class UtilsSFG {
|
|||||||
if (ServerBootSFG.safeguardPassed) {
|
if (ServerBootSFG.safeguardPassed) {
|
||||||
Iris.safeguard(C.BLUE + "0 Conflicts found");
|
Iris.safeguard(C.BLUE + "0 Conflicts found");
|
||||||
} else {
|
} else {
|
||||||
if (IrisSafeguard.instance.unstablemode) {
|
if (IrisSafeguard.unstablemode) {
|
||||||
Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found");
|
Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found");
|
||||||
}
|
}
|
||||||
if (IrisSafeguard.instance.warningmode) {
|
if (IrisSafeguard.warningmode) {
|
||||||
Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found");
|
Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +37,12 @@ public class UtilsSFG {
|
|||||||
}
|
}
|
||||||
if (ServerBootSFG.unsuportedversion) {
|
if (ServerBootSFG.unsuportedversion) {
|
||||||
Iris.safeguard(C.RED + "Server Version");
|
Iris.safeguard(C.RED + "Server Version");
|
||||||
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.21.1");
|
Iris.safeguard(C.RED + "- Iris only supports 1.20.1 > 1.21.4");
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.missingDimensionTypes) {
|
||||||
|
Iris.safeguard(C.RED + "Dimension Types");
|
||||||
|
Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded.");
|
||||||
|
Iris.safeguard(C.RED + "- If this still happens after a restart please contact support.");
|
||||||
}
|
}
|
||||||
if (!ServerBootSFG.passedserversoftware) {
|
if (!ServerBootSFG.passedserversoftware) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||||
@@ -69,13 +56,13 @@ public class UtilsSFG {
|
|||||||
Iris.safeguard(C.YELLOW + "Insufficient Disk Space");
|
Iris.safeguard(C.YELLOW + "Insufficient Disk Space");
|
||||||
Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+.");
|
Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+.");
|
||||||
}
|
}
|
||||||
if (!ServerBootSFG.isJDK17) {
|
if (!ServerBootSFG.isCorrectJDK) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
||||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JDK " + Iris.getJavaVersion());
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JDK " + Iris.getJavaVersion());
|
||||||
}
|
}
|
||||||
if (ServerBootSFG.isJRE) {
|
if (ServerBootSFG.isJRE) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported Server JDK");
|
Iris.safeguard(C.YELLOW + "Unsupported Server JDK");
|
||||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JRE " + Iris.getJavaVersion());
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JRE " + Iris.getJavaVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2024 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.core.safeguard.handler;
|
|
||||||
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
|
||||||
|
|
||||||
public class onCommandWarning implements Listener {
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
|
||||||
if (IrisSettings.get().getSafeguard().userUnstableWarning && IrisSafeguard.instance.unstablemode) {
|
|
||||||
String command = event.getMessage();
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (command.startsWith("/iris")) {
|
|
||||||
VolmitSender sender = new VolmitSender(player);
|
|
||||||
boolean perm = sender.hasPermission("iris.all") || sender.isOp();
|
|
||||||
if (perm) {
|
|
||||||
sender.sendMessage(C.DARK_GRAY + "[" + C.RED + "!" + C.DARK_GRAY + "]" + C.DARK_RED + "Iris is running unstably! Please resolve this.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user