mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-18 06:41:08 +00:00
@@ -31,7 +31,7 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
||||||
5. Quit & Reopen Terminal and verify with `echo $JAVA_HOME`. It should print a directory
|
5. Quit & Reopen Terminal and verify with `echo $JAVA_HOME`. It should print a directory
|
||||||
3. If this is your first time building Iris for MC 1.18+ run `gradlew setup` inside the root Iris project folder.
|
3. If this is your first time building Iris for MC 1.18+ run `gradlew setup` inside the root Iris project folder.
|
||||||
Otherwise, skip this step. Grab a coffee, this may take up to 5 minutes depending on your cpu & internet connection.
|
Otherwise, skip this step. Grab a coffee, this may take up to 45 minutes depending on your cpu & internet connection.
|
||||||
4. Once the project has setup, run `gradlew iris`
|
4. Once the project has setup, run `gradlew iris`
|
||||||
5. The Iris jar will be placed in `Iris/build/Iris-XXX-XXX.jar` Enjoy! Consider supporting us by buying it on spigot!
|
5. The Iris jar will be placed in `Iris/build/Iris-XXX-XXX.jar` Enjoy! Consider supporting us by buying it on spigot!
|
||||||
|
|
||||||
|
|||||||
+49
-17
@@ -21,12 +21,12 @@ import java.util.function.Consumer
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id "com.github.johnrengelman.shadow" version "7.1.2"
|
id "io.github.goooler.shadow" version "8.1.7"
|
||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
version '3.2.6-1.19.2-1.20.4'
|
version '3.2.6-1.19.2-1.20.4'
|
||||||
def specialSourceVersion = '1.11.0' //[NMS]
|
def specialSourceVersion = '1.11.4' //[NMS]
|
||||||
|
|
||||||
// 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,8 +43,8 @@ registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/serve
|
|||||||
registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins')
|
registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins')
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
|
|
||||||
def NMS_BINDINGS = Map.of(
|
def NMS_BINDINGS = Map.of(
|
||||||
|
"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",
|
||||||
@@ -52,11 +52,15 @@ def NMS_BINDINGS = Map.of(
|
|||||||
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
||||||
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
||||||
)
|
)
|
||||||
|
def JVM_VERSION = Map.of(
|
||||||
|
"v1_20_R4", 21,
|
||||||
|
)
|
||||||
NMS_BINDINGS.each {
|
NMS_BINDINGS.each {
|
||||||
def key = it.key
|
def key = it.key
|
||||||
def value = it.value
|
def value = it.value
|
||||||
def nms = value.split("-")[0];
|
def nms = value.split("-")[0];
|
||||||
project(":nms:${key}") {
|
project(":nms:${key}") {
|
||||||
|
apply plugin: 'java'
|
||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
apply plugin: 'de.undercouch.download'
|
apply plugin: 'de.undercouch.download'
|
||||||
|
|
||||||
@@ -65,9 +69,10 @@ NMS_BINDINGS.each {
|
|||||||
compileOnly "org.spigotmc:spigot-api:${value}"
|
compileOnly "org.spigotmc:spigot-api:${value}"
|
||||||
compileOnly "org.bukkit:craftbukkit:${value}:remapped-mojang" //[NMS]
|
compileOnly "org.bukkit:craftbukkit:${value}:remapped-mojang" //[NMS]
|
||||||
}
|
}
|
||||||
def buildToolsJar = new File(rootProject.buildDir, "tools/BuildTools.jar")
|
def buildToolsJar = new File(rootProject.layout.buildDirectory.asFile.get(), "tools/BuildTools.jar")
|
||||||
def specialSourceJar = new File(rootProject.buildDir, "tools/SpecialSource.jar")
|
def specialSourceJar = new File(rootProject.layout.buildDirectory.asFile.get(), "tools/SpecialSource.jar")
|
||||||
|
|
||||||
|
def buildDir = layout.buildDirectory.asFile.get();
|
||||||
def buildToolsFolder = new File(buildDir, "buildtools")
|
def buildToolsFolder = new File(buildDir, "buildtools")
|
||||||
def specialSourceFolder = new File(buildDir, "specialsource")
|
def specialSourceFolder = new File(buildDir, "specialsource")
|
||||||
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nms + ".jar")
|
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nms + ".jar")
|
||||||
@@ -82,6 +87,22 @@ NMS_BINDINGS.each {
|
|||||||
def m2s = m2.getAbsolutePath();
|
def m2s = m2.getAbsolutePath();
|
||||||
|
|
||||||
// ======================== Building Mapped Jars =============================
|
// ======================== Building Mapped Jars =============================
|
||||||
|
def targetJavaVersion = JVM_VERSION.getOrDefault(key, 17)
|
||||||
|
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||||
|
def javaLanguageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||||||
|
project.java.sourceCompatibility = javaVersion
|
||||||
|
project.java.targetCompatibility = javaVersion
|
||||||
|
project.java.toolchain.languageVersion = javaLanguageVersion
|
||||||
|
def launcher = javaToolchains.launcherFor(java.toolchain).get()
|
||||||
|
def javaHome = launcher.executablePath.getAsFile().parentFile.parentFile.getAbsolutePath()
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.release.set(targetJavaVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaExec).configureEach {
|
||||||
|
javaLauncher.set(launcher)
|
||||||
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
executeBuildTools = new Runnable() {
|
executeBuildTools = new Runnable() {
|
||||||
@@ -99,6 +120,7 @@ NMS_BINDINGS.each {
|
|||||||
if (!buildToolsHint.exists()) {
|
if (!buildToolsHint.exists()) {
|
||||||
buildToolsFolder.mkdirs()
|
buildToolsFolder.mkdirs()
|
||||||
project.javaexec {
|
project.javaexec {
|
||||||
|
executable = launcher.executablePath
|
||||||
classpath = files(buildToolsJar)
|
classpath = files(buildToolsJar)
|
||||||
workingDir = buildToolsFolder
|
workingDir = buildToolsFolder
|
||||||
args = [
|
args = [
|
||||||
@@ -108,16 +130,14 @@ NMS_BINDINGS.each {
|
|||||||
"craftbukkit",
|
"craftbukkit",
|
||||||
"--remap"
|
"--remap"
|
||||||
]
|
]
|
||||||
|
def env = new HashMap(environment)
|
||||||
|
env.put("JAVA_HOME", javaHome)
|
||||||
|
environment = env
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks.register("executeBuildTools") {
|
|
||||||
doLast {
|
|
||||||
property("executeBuildTools").run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.build.doLast {
|
tasks.build.doLast {
|
||||||
//Download
|
//Download
|
||||||
@@ -137,6 +157,7 @@ NMS_BINDINGS.each {
|
|||||||
|
|
||||||
//obfuscate
|
//obfuscate
|
||||||
javaexec {
|
javaexec {
|
||||||
|
executable = launcher.executablePath
|
||||||
workingDir = specialSourceFolder
|
workingDir = specialSourceFolder
|
||||||
classpath = files(specialSourceJar,
|
classpath = files(specialSourceJar,
|
||||||
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-mojang.jar"))
|
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-mojang.jar"))
|
||||||
@@ -151,10 +172,14 @@ NMS_BINDINGS.each {
|
|||||||
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-mojang.txt",
|
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-mojang.txt",
|
||||||
"--reverse",
|
"--reverse",
|
||||||
]
|
]
|
||||||
|
def env = new HashMap(environment)
|
||||||
|
env.put("JAVA_HOME", javaHome)
|
||||||
|
environment = env
|
||||||
}
|
}
|
||||||
|
|
||||||
//remap
|
//remap
|
||||||
javaexec {
|
javaexec {
|
||||||
|
executable = launcher.executablePath
|
||||||
workingDir = specialSourceFolder
|
workingDir = specialSourceFolder
|
||||||
classpath = files(specialSourceJar,
|
classpath = files(specialSourceJar,
|
||||||
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-obf.jar"))
|
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-obf.jar"))
|
||||||
@@ -168,6 +193,9 @@ NMS_BINDINGS.each {
|
|||||||
"-m",
|
"-m",
|
||||||
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-spigot.csrg"
|
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-spigot.csrg"
|
||||||
]
|
]
|
||||||
|
def env = new HashMap(environment)
|
||||||
|
env.put("JAVA_HOME", javaHome)
|
||||||
|
environment = env
|
||||||
}
|
}
|
||||||
//copy
|
//copy
|
||||||
copy {
|
copy {
|
||||||
@@ -182,6 +210,10 @@ NMS_BINDINGS.each {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
NMS_BINDINGS.each {
|
||||||
|
dependsOn(":nms:${it.key}:build")
|
||||||
|
from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}.jar")
|
||||||
|
}
|
||||||
NMS_BINDINGS.each {dependsOn(":nms:${it.key}:build")}
|
NMS_BINDINGS.each {dependsOn(":nms:${it.key}:build")}
|
||||||
dependsOn(':com.volmit.gui:build')
|
dependsOn(':com.volmit.gui:build')
|
||||||
|
|
||||||
@@ -195,9 +227,6 @@ shadowJar {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':core')
|
implementation project(':core')
|
||||||
NMS_BINDINGS.each {
|
|
||||||
implementation project(":nms:${it.key}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
@@ -230,7 +259,6 @@ allprojects {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Provided or Classpath
|
// Provided or Classpath
|
||||||
// implementation project(':com.volmit.gui')
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||||
|
|
||||||
@@ -240,6 +268,8 @@ allprojects {
|
|||||||
implementation "net.kyori:adventure-text-minimessage:4.13.1"
|
implementation "net.kyori:adventure-text-minimessage:4.13.1"
|
||||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.2'
|
implementation 'net.kyori:adventure-platform-bukkit:4.3.2'
|
||||||
implementation 'net.kyori:adventure-api:4.13.1'
|
implementation 'net.kyori:adventure-api:4.13.1'
|
||||||
|
//implementation 'org.bytedeco:javacpp:1.5.10'
|
||||||
|
//implementation 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
|
||||||
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
||||||
|
|
||||||
// Dynamically Loaded
|
// Dynamically Loaded
|
||||||
@@ -289,8 +319,8 @@ if (JavaVersion.current().toString() != "17") {
|
|||||||
|
|
||||||
task iris(type: Copy) {
|
task iris(type: Copy) {
|
||||||
group "iris"
|
group "iris"
|
||||||
from new File(buildDir, "libs/Iris-${version}.jar")
|
from new File(layout.buildDirectory.asFile.get(), "libs/Iris-${version}.jar")
|
||||||
into buildDir
|
into layout.buildDirectory.asFile.get()
|
||||||
dependsOn(build)
|
dependsOn(build)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +343,9 @@ NMS_BINDINGS.keySet().forEach {
|
|||||||
tasks.register("setup-${nms}") {
|
tasks.register("setup-${nms}") {
|
||||||
group "iris"
|
group "iris"
|
||||||
dependsOn(":nms:${nms}:clean")
|
dependsOn(":nms:${nms}:clean")
|
||||||
dependsOn(":nms:${nms}:executeBuildTools")
|
doLast {
|
||||||
|
project(":nms:${nms}").property("executeBuildTools").run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -19,7 +19,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id "io.freefair.lombok" version "6.3.0"
|
id "io.freefair.lombok" version "8.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
def apiVersion = '1.19'
|
def apiVersion = '1.19'
|
||||||
@@ -35,6 +35,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/' }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +67,7 @@ dependencies {
|
|||||||
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'
|
||||||
compileOnly 'net.Indyuce:MMOItems-API:6.9.5-SNAPSHOT'
|
compileOnly 'net.Indyuce:MMOItems-API:6.9.5-SNAPSHOT'
|
||||||
|
compileOnly 'com.willfp:EcoItems:5.44.0'
|
||||||
//implementation files('libs/CustomItems.jar')
|
//implementation files('libs/CustomItems.jar')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ import java.lang.management.OperatingSystemMXBean;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -457,7 +458,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
instance = this;
|
instance = this;
|
||||||
InitializeSafeguard();
|
InitializeSafeguard();
|
||||||
ByteBuddyAgent.install();
|
ByteBuddyAgent.install();
|
||||||
boolean configured;
|
|
||||||
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));
|
||||||
@@ -473,7 +473,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
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);
|
||||||
configured = ServerConfigurator.postConfigure();
|
installMainDimension();
|
||||||
if (!IrisSafeguard.instance.acceptUnstable && IrisSafeguard.instance.unstablemode) {
|
if (!IrisSafeguard.instance.acceptUnstable && IrisSafeguard.instance.unstablemode) {
|
||||||
Iris.info(C.RED + "World loading has been disabled until the incompatibility is resolved.");
|
Iris.info(C.RED + "World loading has been disabled until the incompatibility is resolved.");
|
||||||
Iris.info(C.DARK_RED + "Alternatively, go to plugins/iris/settings.json and set ignoreBootMode to true.");
|
Iris.info(C.DARK_RED + "Alternatively, go to plugins/iris/settings.json and set ignoreBootMode to true.");
|
||||||
@@ -486,7 +486,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
J.ar(this::checkConfigHotload, 60);
|
J.ar(this::checkConfigHotload, 60);
|
||||||
J.sr(this::tickQueue, 0);
|
J.sr(this::tickQueue, 0);
|
||||||
J.s(this::setupPapi);
|
J.s(this::setupPapi);
|
||||||
if (!configured) J.a(ServerConfigurator::configure, 20);
|
J.a(ServerConfigurator::configure, 20);
|
||||||
splash();
|
splash();
|
||||||
UtilsSFG.splash();
|
UtilsSFG.splash();
|
||||||
autoStartStudio();
|
autoStartStudio();
|
||||||
@@ -686,6 +686,48 @@ 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) {
|
||||||
|
|||||||
@@ -19,33 +19,15 @@
|
|||||||
package com.volmit.iris.core;
|
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.nms.INMS;
|
|
||||||
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.IrisRange;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KSet;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
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 java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getServer;
|
|
||||||
|
|
||||||
public class ServerConfigurator {
|
public class ServerConfigurator {
|
||||||
public static void configure() {
|
public static void configure() {
|
||||||
IrisSettings.IrisSettingsAutoconfiguration s = IrisSettings.get().getAutoConfiguration();
|
IrisSettings.IrisSettingsAutoconfiguration s = IrisSettings.get().getAutoConfiguration();
|
||||||
@@ -56,16 +38,6 @@ public class ServerConfigurator {
|
|||||||
if (s.isConfigurePaperWatchdogDelay()) {
|
if (s.isConfigurePaperWatchdogDelay()) {
|
||||||
J.attempt(ServerConfigurator::increasePaperWatchdog);
|
J.attempt(ServerConfigurator::increasePaperWatchdog);
|
||||||
}
|
}
|
||||||
|
|
||||||
installDataPacks(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean postConfigure() {
|
|
||||||
if(postVerifyDataPacks(true)) {
|
|
||||||
configure();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
||||||
@@ -81,6 +53,7 @@ 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();
|
||||||
@@ -94,191 +67,4 @@ public class ServerConfigurator {
|
|||||||
f.save(spigotConfig);
|
f.save(spigotConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<File> getDatapacksFolder() {
|
|
||||||
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
|
|
||||||
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
|
||||||
}
|
|
||||||
KList<File> worlds = new KList<>();
|
|
||||||
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
|
|
||||||
if (worlds.isEmpty()) {
|
|
||||||
worlds.add(new File(getMainWorldFolder(), "datapacks"));
|
|
||||||
}
|
|
||||||
return worlds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static File getMainWorldFolder() {
|
|
||||||
try {
|
|
||||||
Properties prop = new Properties();
|
|
||||||
prop.load(new FileInputStream("server.properties"));
|
|
||||||
String world = prop.getProperty("level-name");
|
|
||||||
return new File(Bukkit.getWorldContainer(), world);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean postVerifyDataPacks(boolean fast) {
|
|
||||||
try {
|
|
||||||
File datapacksFolder = new File(getMainWorldFolder(), "datapacks");
|
|
||||||
File IrisDatapacks = new File(datapacksFolder, "iris");
|
|
||||||
if (!datapacksFolder.exists() || !IrisDatapacks.exists()) {
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void installDataPacks(boolean fullInstall) {
|
|
||||||
Iris.info("Checking Data Packs...");
|
|
||||||
File packs = new File("plugins/Iris/packs");
|
|
||||||
if (packs.exists()) {
|
|
||||||
for (File i : packs.listFiles()) {
|
|
||||||
if (i.isDirectory()) {
|
|
||||||
Iris.verbose("Checking Pack: " + i.getPath());
|
|
||||||
IrisData data = IrisData.get(i);
|
|
||||||
File dims = new File(i, "dimensions");
|
|
||||||
|
|
||||||
if (dims.exists()) {
|
|
||||||
for (File j : dims.listFiles()) {
|
|
||||||
if (j.getName().endsWith(".json")) {
|
|
||||||
IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]);
|
|
||||||
|
|
||||||
if (dim == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
|
||||||
for (File dpack : getDatapacksFolder()) {
|
|
||||||
dim.installDataPack(() -> data, dpack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info("Data Packs Setup!");
|
|
||||||
|
|
||||||
if (fullInstall)
|
|
||||||
verifyDataPacksPost(IrisSettings.get().getAutoConfiguration().isAutoRestartOnCustomBiomeInstall());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void verifyDataPacksPost(boolean allowRestarting) {
|
|
||||||
File packs = new File("plugins/Iris/packs");
|
|
||||||
|
|
||||||
boolean bad = false;
|
|
||||||
if (packs.exists()) {
|
|
||||||
for (File i : packs.listFiles()) {
|
|
||||||
if (i.isDirectory()) {
|
|
||||||
Iris.verbose("Checking Pack: " + i.getPath());
|
|
||||||
IrisData data = IrisData.get(i);
|
|
||||||
File dims = new File(i, "dimensions");
|
|
||||||
|
|
||||||
if (dims.exists()) {
|
|
||||||
for (File j : dims.listFiles()) {
|
|
||||||
if (j.getName().endsWith(".json")) {
|
|
||||||
IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]);
|
|
||||||
|
|
||||||
if (dim == null) {
|
|
||||||
Iris.error("Failed to load " + j.getPath() + " ");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verifyDataPackInstalled(dim)) {
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bad) {
|
|
||||||
// Iris.info("");
|
|
||||||
Iris.info( "Hotloading all Datapacks!");
|
|
||||||
if (INMS.get().supportsDataPacks()) {
|
|
||||||
for (File folder : getDatapacksFolder()) {
|
|
||||||
INMS.get().loadDatapack(folder, false);
|
|
||||||
}
|
|
||||||
Iris.info("Datapacks Hotloaded!");
|
|
||||||
Iris.info(C.YELLOW + "============================================================================");
|
|
||||||
Iris.info(C.ITALIC + "" + C.YELLOW + "To ensure the stability of custom biome generation, a server restart is necessary.");
|
|
||||||
Iris.info(C.ITALIC + "" + C.YELLOW + "While datapacks have been hotloaded, a complete restart is advised.");
|
|
||||||
Iris.info(C.YELLOW + "----------------------------------------------------------------------------");
|
|
||||||
Iris.info(C.UNDERLINE + "" + C.YELLOW + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!");
|
|
||||||
Iris.info(C.YELLOW + "============================================================================");
|
|
||||||
|
|
||||||
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) {
|
|
||||||
IrisData idm = IrisData.get(Iris.instance.getDataFolder("packs", dimension.getLoadKey()));
|
|
||||||
KSet<String> keys = new KSet<>();
|
|
||||||
boolean warn = false;
|
|
||||||
|
|
||||||
for (IrisBiome i : dimension.getAllBiomes(() -> idm)) {
|
|
||||||
if (i.isCustom()) {
|
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
|
||||||
keys.add(dimension.getLoadKey() + ":" + j.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!INMS.get().supportsDataPacks()) {
|
|
||||||
if (!keys.isEmpty()) {
|
|
||||||
Iris.warn("===================================================================================");
|
|
||||||
Iris.warn("Pack " + dimension.getLoadKey() + " 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes");
|
|
||||||
Iris.error("Queued for Datapack Hotload.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return !warn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
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.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
import com.volmit.iris.core.service.IrisEngineSVC;
|
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||||
@@ -152,10 +154,12 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
@Param(description = "The pack to bench", aliases = {"pack"})
|
@Param(description = "The pack to bench", aliases = {"pack"})
|
||||||
IrisDimension dimension,
|
IrisDimension dimension,
|
||||||
@Param(description = "Headless", defaultValue = "false")
|
@Param(description = "Headless", defaultValue = "false")
|
||||||
boolean headless
|
boolean headless,
|
||||||
|
@Param(description = "GUI", defaultValue = "false")
|
||||||
|
boolean gui
|
||||||
) {
|
) {
|
||||||
Iris.info("test");
|
Iris.info("test");
|
||||||
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1, headless);
|
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1, headless, gui);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ 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.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.pregenerator.ChunkUpdater;
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ 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;
|
||||||
@@ -52,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(Material.GRASS, Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
private static final Set<Material> skipBlocks = Set.of(E.getOrDefault(Material.class, "GRASS", "SHORT_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) {
|
||||||
|
|||||||
@@ -20,21 +20,16 @@ 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.ServerConfigurator;
|
|
||||||
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.loader.IrisData;
|
|
||||||
import com.volmit.iris.core.nms.INMS;
|
|
||||||
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.IrisConverter;
|
|
||||||
import com.volmit.iris.core.tools.IrisNoiseBenchmark;
|
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.*;
|
||||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import com.volmit.iris.engine.platform.studio.StudioGenerator;
|
|
||||||
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.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
@@ -43,30 +38,23 @@ 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.decree.specialhandlers.NullablePlayerHandler;
|
|
||||||
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.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.entity.Player;
|
|
||||||
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.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
@@ -85,7 +73,6 @@ import java.util.Date;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
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.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
||||||
@@ -286,7 +273,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Hotload a studio", aliases = {"reload", "h"})
|
@Decree(description = "Hotload a studio", aliases = {"reload", "h"})
|
||||||
public void hotload(@Param(defaultValue = "false") boolean reloadDataPack) {
|
public void hotload() {
|
||||||
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
if (!Iris.service(StudioSVC.class).isProjectOpen()) {
|
||||||
sender().sendMessage(C.RED + "No studio world open!");
|
sender().sendMessage(C.RED + "No studio world open!");
|
||||||
return;
|
return;
|
||||||
@@ -294,15 +281,6 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
var provider = Iris.service(StudioSVC.class).getActiveProject().getActiveProvider();
|
var provider = Iris.service(StudioSVC.class).getActiveProject().getActiveProvider();
|
||||||
provider.getEngine().hotload();
|
provider.getEngine().hotload();
|
||||||
sender().sendMessage(C.GREEN + "Hotloaded");
|
sender().sendMessage(C.GREEN + "Hotloaded");
|
||||||
if (reloadDataPack) {
|
|
||||||
var world = provider.getTarget().getWorld().realWorld();
|
|
||||||
if (world == null) {
|
|
||||||
sender().sendMessage(C.RED + "Failed to reload datapacks.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean success = INMS.get().loadDatapack(new File(world.getWorldFolder(), "datapacks"), true);
|
|
||||||
sender().sendMessage(success ? C.GREEN + "Reloaded datapacks." : C.RED + "Failed to reload datapacks.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@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)
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
|
import com.willfp.ecoitems.items.EcoItem;
|
||||||
|
import com.willfp.ecoitems.items.EcoItems;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
|
public class EcoItemsDataProvider extends ExternalDataProvider {
|
||||||
|
private WrappedField<EcoItem, ItemStack> itemStack;
|
||||||
|
private WrappedField<EcoItem, NamespacedKey> id;
|
||||||
|
|
||||||
|
public EcoItemsDataProvider() {
|
||||||
|
super("EcoItems");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up EcoItems Link...");
|
||||||
|
itemStack = new WrappedField<>(EcoItem.class, "_itemStack");
|
||||||
|
if (this.itemStack.hasFailed()) {
|
||||||
|
Iris.error("Failed to set up EcoItems Link: Unable to fetch ItemStack field!");
|
||||||
|
}
|
||||||
|
id = new WrappedField<>(EcoItem.class, "id");
|
||||||
|
if (this.id.hasFailed()) {
|
||||||
|
Iris.error("Failed to set up EcoItems Link: Unable to fetch id field!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||||
|
EcoItem item = EcoItems.INSTANCE.getByID(itemId.key());
|
||||||
|
if (item == null) throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key());
|
||||||
|
return itemStack.get(item).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
return new Identifier[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (EcoItem item : EcoItems.INSTANCE.values()) {
|
||||||
|
try {
|
||||||
|
Identifier key = Identifier.fromNamespacedKey(id.get(item));
|
||||||
|
if (getItemStack(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||||
|
return id.namespace().equalsIgnoreCase("ecoitems") && isItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@ public record Identifier(String namespace, String key) {
|
|||||||
|
|
||||||
private static final String DEFAULT_NAMESPACE = "minecraft";
|
private static final String DEFAULT_NAMESPACE = "minecraft";
|
||||||
|
|
||||||
|
public static Identifier fromNamespacedKey(NamespacedKey key) {
|
||||||
|
return new Identifier(key.getNamespace(), key.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
public static Identifier fromString(String id) {
|
public static Identifier fromString(String id) {
|
||||||
String[] strings = id.split(":", 2);
|
String[] strings = id.split(":", 2);
|
||||||
if (strings.length == 1) {
|
if (strings.length == 1) {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import java.io.Closeable;
|
|||||||
|
|
||||||
public interface IHeadless extends Closeable {
|
public interface IHeadless extends Closeable {
|
||||||
|
|
||||||
void saveAll();
|
void save();
|
||||||
|
|
||||||
@RegionCoordinates
|
@ChunkCoordinates
|
||||||
boolean exists(int x, int z);
|
boolean exists(int x, int z);
|
||||||
|
|
||||||
@RegionCoordinates
|
@RegionCoordinates
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ 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.Map;
|
||||||
|
|
||||||
public class INMS {
|
public class INMS {
|
||||||
|
private static final Map<String, String> REVISION = Map.of(
|
||||||
|
"1.20.5", "v1_20_R4",
|
||||||
|
"1.20.6", "v1_20_R4"
|
||||||
|
);
|
||||||
//@done
|
//@done
|
||||||
private static final INMSBinding binding = bind();
|
private static final INMSBinding binding = bind();
|
||||||
|
|
||||||
@@ -37,7 +43,12 @@ public class INMS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Bukkit.getServer().getClass().getCanonicalName().split("\\Q.\\E")[3];
|
String name = Bukkit.getServer().getClass().getCanonicalName();
|
||||||
|
if (name.equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||||
|
return REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0], "BUKKIT");
|
||||||
|
} else {
|
||||||
|
return name.split("\\Q.\\E")[3];
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
Iris.error("Failed to determine server nms version!");
|
Iris.error("Failed to determine server nms version!");
|
||||||
|
|||||||
@@ -18,11 +18,12 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
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.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.documentation.RegionCoordinates;
|
|
||||||
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;
|
||||||
@@ -40,8 +41,6 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
|
|||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public interface INMSBinding {
|
public interface INMSBinding {
|
||||||
boolean hasTile(Location l);
|
boolean hasTile(Location l);
|
||||||
|
|
||||||
@@ -115,10 +114,14 @@ public interface INMSBinding {
|
|||||||
|
|
||||||
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
||||||
|
|
||||||
boolean loadDatapack(File datapackFolder, boolean replace);
|
default DataVersion getDataVersion() {
|
||||||
|
return DataVersion.V1192;
|
||||||
|
}
|
||||||
|
|
||||||
boolean registerDimension(String name, IrisDimension dimension);
|
boolean registerDimension(String name, IrisDimension dimension);
|
||||||
|
|
||||||
|
boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace);
|
||||||
|
|
||||||
void injectBukkit();
|
void injectBukkit();
|
||||||
|
|
||||||
default IHeadless createHeadless(Engine engine) {
|
default IHeadless createHeadless(Engine engine) {
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1206.DataFixerV1206;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
//https://minecraft.wiki/w/Pack_format
|
||||||
|
@Getter
|
||||||
|
public enum DataVersion {
|
||||||
|
V1192("1.19.2", 10, DataFixerV1192::new),
|
||||||
|
V1205("1.20.6", 41, DataFixerV1206::new);
|
||||||
|
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
private final Supplier<IDataFixer> constructor;
|
||||||
|
private final String version;
|
||||||
|
private final int packFormat;
|
||||||
|
|
||||||
|
DataVersion(String version, int packFormat, Supplier<IDataFixer> constructor) {
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.packFormat = packFormat;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDataFixer get() {
|
||||||
|
return cache.computeIfAbsent(this, k -> constructor.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IDataFixer getDefault() {
|
||||||
|
return INMS.get().getDataVersion().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataVersion getLatest() {
|
||||||
|
return values()[values().length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
public interface IDataFixer {
|
||||||
|
|
||||||
|
JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json);
|
||||||
|
|
||||||
|
JSONObject fixDimension(JSONObject json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack.v1192;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
public class DataFixerV1192 implements IDataFixer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixDimension(JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack.v1206;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class DataFixerV1206 implements IDataFixer {
|
||||||
|
@Override
|
||||||
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
int spawnRarity = biome.getSpawnRarity();
|
||||||
|
if (spawnRarity > 0) {
|
||||||
|
json.put("creature_spawn_probability", Math.min(spawnRarity/20d, 0.9999999));
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawns = biome.getSpawns();
|
||||||
|
if (spawns != null && spawns.isNotEmpty()) {
|
||||||
|
JSONObject spawners = new JSONObject();
|
||||||
|
KMap<IrisBiomeCustomSpawnType, JSONArray> groups = new KMap<>();
|
||||||
|
|
||||||
|
for (IrisBiomeCustomSpawn i : spawns) {
|
||||||
|
JSONArray g = groups.computeIfAbsent(i.getGroup(), (k) -> new JSONArray());
|
||||||
|
JSONObject o = new JSONObject();
|
||||||
|
o.put("type", "minecraft:" + i.getType().name().toLowerCase());
|
||||||
|
o.put("weight", i.getWeight());
|
||||||
|
o.put("minCount", Math.min(i.getMinCount()/20d, 0));
|
||||||
|
o.put("maxCount", Math.min(i.getMaxCount()/20d, 0.9999999));
|
||||||
|
g.put(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisBiomeCustomSpawnType i : groups.k()) {
|
||||||
|
spawners.put(i.name().toLowerCase(Locale.ROOT), groups.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
json.put("spawners", spawners);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixDimension(JSONObject json) {
|
||||||
|
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
||||||
|
return json;
|
||||||
|
var value = (JSONObject) lightLevel.remove("value");
|
||||||
|
lightLevel.put("max_inclusive", value.get("max_inclusive"));
|
||||||
|
lightLevel.put("min_inclusive", value.get("min_inclusive"));
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ 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.BlockPos;
|
import com.volmit.iris.core.nms.container.BlockPos;
|
||||||
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.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;
|
||||||
@@ -108,12 +109,12 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File datapackFolder, boolean replace) {
|
public boolean registerDimension(String name, IrisDimension dimension) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean registerDimension(String name, IrisDimension dimension) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,11 +82,8 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
private void completeChunk(int x, int z, PregenListener listener) {
|
private void completeChunk(int x, int z, PregenListener listener) {
|
||||||
try {
|
try {
|
||||||
future.add(PaperLib.getChunkAtAsync(world, x, z, true).thenApply((i) -> {
|
future.add(PaperLib.getChunkAtAsync(world, x, z, true).thenApply((i) -> {
|
||||||
if (i == null) {
|
if (i == null) return 0;
|
||||||
|
lastUse.put(i, M.ms());
|
||||||
}
|
|
||||||
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
|
||||||
lastUse.put(c, M.ms());
|
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+23
-32
@@ -1,30 +1,29 @@
|
|||||||
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.nms.IHeadless;
|
import com.volmit.iris.core.nms.IHeadless;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
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.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class HeadlessPregenMethod implements PregeneratorMethod {
|
public class HeadlessPregenMethod implements PregeneratorMethod {
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final IHeadless headless;
|
private final IHeadless headless;
|
||||||
private final MultiBurst burst;
|
private final Semaphore semaphore;
|
||||||
private final KList<Future<?>> futures;
|
private final int max;
|
||||||
|
|
||||||
public HeadlessPregenMethod(Engine engine) {
|
public HeadlessPregenMethod(Engine engine) {
|
||||||
|
this.max = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism());
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.headless = INMS.get().createHeadless(engine);
|
this.headless = INMS.get().createHeadless(engine);
|
||||||
this.burst = new MultiBurst("Iris Headless", Thread.MAX_PRIORITY);
|
this.semaphore = new Semaphore(max);
|
||||||
this.futures = new KList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,9 +31,10 @@ public class HeadlessPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
waitForChunksPartial(0);
|
try {
|
||||||
burst.close();
|
semaphore.acquire(max);
|
||||||
headless.saveAll();
|
} catch (InterruptedException ignored) {}
|
||||||
|
headless.save();
|
||||||
try {
|
try {
|
||||||
headless.close();
|
headless.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -45,7 +45,7 @@ public class HeadlessPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save() {
|
||||||
headless.saveAll();
|
headless.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,34 +63,25 @@ public class HeadlessPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateChunk(int x, int z, PregenListener listener) {
|
public void generateChunk(int x, int z, PregenListener listener) {
|
||||||
futures.removeIf(Future::isDone);
|
try {
|
||||||
waitForChunksPartial(512);
|
semaphore.acquire();
|
||||||
futures.add(burst.complete(() -> {
|
} catch (InterruptedException ignored) {
|
||||||
|
semaphore.release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MultiBurst.burst.complete(() -> {
|
||||||
|
try {
|
||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
headless.generateChunk(x, z);
|
headless.generateChunk(x, z);
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
}));
|
} finally {
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mantle getMantle() {
|
public Mantle getMantle() {
|
||||||
return engine.getMantle().getMantle();
|
return engine.getMantle().getMantle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForChunksPartial(int maxWaiting) {
|
|
||||||
futures.removeWhere(Objects::isNull);
|
|
||||||
while (futures.size() > maxWaiting) {
|
|
||||||
try {
|
|
||||||
Future<?> i = futures.remove(0);
|
|
||||||
|
|
||||||
if (i == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
i.get();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -119,8 +119,7 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
futures.add(J.sfut(() -> {
|
futures.add(J.sfut(() -> {
|
||||||
world.getChunkAt(x, z);
|
Chunk c = 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);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ public class ServerBootSFG {
|
|||||||
severityHigh++;
|
severityHigh++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getJavaVersion() != 17) {
|
if (!List.of(17, 21).contains(getJavaVersion())) {
|
||||||
isJDK17 = false;
|
isJDK17 = false;
|
||||||
joiner.add("Unsupported Java version");
|
joiner.add("Unsupported Java version");
|
||||||
severityMedium++;
|
severityMedium++;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ 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.20.4");
|
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.20.6");
|
||||||
}
|
}
|
||||||
if (!ServerBootSFG.passedserversoftware) {
|
if (!ServerBootSFG.passedserversoftware) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||||
@@ -53,11 +53,11 @@ public class UtilsSFG {
|
|||||||
}
|
}
|
||||||
if (!ServerBootSFG.isJDK17) {
|
if (!ServerBootSFG.isJDK17) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
||||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 Instead of JDK " + Iris.getJavaVersion());
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) 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 Instead of JRE " + Iris.getJavaVersion());
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JRE " + Iris.getJavaVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ public class ExternalDataSVC implements IrisService {
|
|||||||
if (Bukkit.getPluginManager().getPlugin("MMOItems") != null) {
|
if (Bukkit.getPluginManager().getPlugin("MMOItems") != null) {
|
||||||
Iris.info("MMOItems found, loading MMOItemsDataProvider...");
|
Iris.info("MMOItems found, loading MMOItemsDataProvider...");
|
||||||
}
|
}
|
||||||
|
providers.add(new EcoItemsDataProvider());
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("EcoItems") != null) {
|
||||||
|
Iris.info("EcoItems found, loading EcoItemsDataProvider...");
|
||||||
|
}
|
||||||
|
|
||||||
for (ExternalDataProvider p : providers) {
|
for (ExternalDataProvider p : providers) {
|
||||||
if (p.isReady()) {
|
if (p.isReady()) {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
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.ServerConfigurator;
|
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.pack.IrisPack;
|
import com.volmit.iris.core.pack.IrisPack;
|
||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
@@ -296,7 +295,6 @@ public class StudioSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage("Successfully Aquired " + d.getName());
|
sender.sendMessage("Successfully Aquired " + d.getName());
|
||||||
ServerConfigurator.installDataPacks(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KMap<String, String> getListing(boolean cached) {
|
public KMap<String, String> getListing(boolean cached) {
|
||||||
|
|||||||
@@ -30,9 +30,11 @@ import com.volmit.iris.util.format.C;
|
|||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.WorldMatter;
|
import com.volmit.iris.util.matter.WorldMatter;
|
||||||
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
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 com.volmit.iris.util.scheduling.S;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
@@ -53,6 +55,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class WandSVC implements IrisService {
|
public class WandSVC implements IrisService {
|
||||||
|
private static final Particle CRIT_MAGIC = E.getOrDefault(Particle.class, "CRIT_MAGIC", "CRIT");
|
||||||
|
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
||||||
|
|
||||||
private static ItemStack dust;
|
private static ItemStack dust;
|
||||||
private static ItemStack wand;
|
private static ItemStack wand;
|
||||||
|
|
||||||
@@ -162,11 +167,11 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack createDust() {
|
public static ItemStack createDust() {
|
||||||
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
|
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
|
||||||
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
|
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||||
ItemMeta im = is.getItemMeta();
|
ItemMeta im = is.getItemMeta();
|
||||||
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
|
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
|
||||||
im.setUnbreakable(true);
|
im.setUnbreakable(true);
|
||||||
im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_PLACED_ON, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DESTROYS, ItemFlag.HIDE_ENCHANTS);
|
im.addItemFlags(ItemFlag.values());
|
||||||
im.setLore(new KList<String>().qadd("Right click on a block to reveal it's placement structure!"));
|
im.setLore(new KList<String>().qadd("Right click on a block to reveal it's placement structure!"));
|
||||||
is.setItemMeta(im);
|
is.setItemMeta(im);
|
||||||
|
|
||||||
@@ -206,11 +211,11 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack createWand(Location a, Location b) {
|
public static ItemStack createWand(Location a, Location b) {
|
||||||
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
||||||
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
|
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||||
ItemMeta im = is.getItemMeta();
|
ItemMeta im = is.getItemMeta();
|
||||||
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
|
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
|
||||||
im.setUnbreakable(true);
|
im.setUnbreakable(true);
|
||||||
im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_PLACED_ON, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DESTROYS, ItemFlag.HIDE_ENCHANTS);
|
im.addItemFlags(ItemFlag.values());
|
||||||
im.setLore(new KList<String>().add(locationToString(a), locationToString(b)));
|
im.setLore(new KList<String>().add(locationToString(a), locationToString(b)));
|
||||||
is.setItemMeta(im);
|
is.setItemMeta(im);
|
||||||
|
|
||||||
@@ -311,7 +316,7 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public void draw(Location[] d, Player p) {
|
public void draw(Location[] d, Player p) {
|
||||||
Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
||||||
d[0].getWorld().spawnParticle(Particle.CRIT_MAGIC, d[0], 1, 0.5 + gx.getX(), 0.5 + gx.getY(), 0.5 + gx.getZ(), 0, null, false);
|
d[0].getWorld().spawnParticle(CRIT_MAGIC, d[0], 1, 0.5 + gx.getX(), 0.5 + gx.getY(), 0.5 + gx.getZ(), 0, null, false);
|
||||||
Vector gxx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
Vector gxx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
||||||
d[1].getWorld().spawnParticle(Particle.CRIT, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
|
d[1].getWorld().spawnParticle(Particle.CRIT, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
|
||||||
|
|
||||||
@@ -370,7 +375,7 @@ public class WandSVC implements IrisService {
|
|||||||
int r = color.getRed();
|
int r = color.getRed();
|
||||||
int g = color.getGreen();
|
int g = color.getGreen();
|
||||||
int b = color.getBlue();
|
int b = color.getBlue();
|
||||||
p.spawnParticle(Particle.REDSTONE, lv.getX(), lv.getY(), lv.getZ(), 1, 0, 0, 0, 0, new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), 0.75f));
|
p.spawnParticle(REDSTONE, lv.getX(), lv.getY(), lv.getZ(), 1, 0, 0, 0, 0, new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), 0.75f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,10 @@ package com.volmit.iris.core.tools;
|
|||||||
import com.google.common.util.concurrent.AtomicDouble;
|
import com.google.common.util.concurrent.AtomicDouble;
|
||||||
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.ServerConfigurator;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
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.engine.platform.PlatformChunkGenerator;
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import com.volmit.iris.core.safeguard.UtilsSFG;
|
|
||||||
import com.volmit.iris.util.exceptions.IrisException;
|
import com.volmit.iris.util.exceptions.IrisException;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
@@ -144,7 +141,6 @@ public class IrisCreator {
|
|||||||
.studio(studio)
|
.studio(studio)
|
||||||
.smartVanillaHeight(smartVanillaHeight)
|
.smartVanillaHeight(smartVanillaHeight)
|
||||||
.create();
|
.create();
|
||||||
ServerConfigurator.installDataPacks(false);
|
|
||||||
|
|
||||||
access = (PlatformChunkGenerator) wc.generator();
|
access = (PlatformChunkGenerator) wc.generator();
|
||||||
PlatformChunkGenerator finalAccess1 = access;
|
PlatformChunkGenerator finalAccess1 = access;
|
||||||
|
|||||||
@@ -45,15 +45,17 @@ public class IrisPackBenchmarking {
|
|||||||
private IrisDimension IrisDimension;
|
private IrisDimension IrisDimension;
|
||||||
private int radius;
|
private int radius;
|
||||||
private final boolean headless;
|
private final boolean headless;
|
||||||
|
private final boolean gui;
|
||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
private Engine engine;
|
private Engine engine;
|
||||||
PrecisionStopwatch stopwatch;
|
PrecisionStopwatch stopwatch;
|
||||||
|
|
||||||
public IrisPackBenchmarking(IrisDimension dimension, int r, boolean headless) {
|
public IrisPackBenchmarking(IrisDimension dimension, int r, boolean headless, boolean gui) {
|
||||||
instance = this;
|
instance = this;
|
||||||
this.IrisDimension = dimension;
|
this.IrisDimension = dimension;
|
||||||
this.radius = r;
|
this.radius = r;
|
||||||
this.headless = headless;
|
this.headless = headless;
|
||||||
|
this.gui = gui;
|
||||||
runBenchmark();
|
runBenchmark();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +155,7 @@ public class IrisPackBenchmarking {
|
|||||||
return new IrisEngine(new EngineTarget(world, dim, data), false);
|
return new IrisEngine(new EngineTarget(world, dim, data), false);
|
||||||
}
|
}
|
||||||
return IrisToolbelt.access(IrisToolbelt.createWorld()
|
return IrisToolbelt.access(IrisToolbelt.createWorld()
|
||||||
.dimension(IrisDimension.getName())
|
.dimension(IrisDimension.getLoadKey())
|
||||||
.name("benchmark")
|
.name("benchmark")
|
||||||
.seed(1337)
|
.seed(1337)
|
||||||
.studio(false)
|
.studio(false)
|
||||||
@@ -169,7 +171,7 @@ public class IrisPackBenchmarking {
|
|||||||
int z = 0;
|
int z = 0;
|
||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.gui(false)
|
.gui(gui)
|
||||||
.center(new Position2(x, z))
|
.center(new Position2(x, z))
|
||||||
.width(5)
|
.width(5)
|
||||||
.height(5)
|
.height(5)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package com.volmit.iris.core.wand;
|
|||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.misc.E;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -29,6 +30,7 @@ import org.bukkit.util.Vector;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
public class WandSelection {
|
public class WandSelection {
|
||||||
|
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
||||||
private final Cuboid c;
|
private final Cuboid c;
|
||||||
private final Player p;
|
private final Player p;
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ public class WandSelection {
|
|||||||
int g = color.getGreen();
|
int g = color.getGreen();
|
||||||
int b = color.getBlue();
|
int b = color.getBlue();
|
||||||
|
|
||||||
p.spawnParticle(Particle.REDSTONE, a.getX(), a.getY(), a.getZ(),
|
p.spawnParticle(REDSTONE, a.getX(), a.getY(), a.getZ(),
|
||||||
1, 0, 0, 0, 0,
|
1, 0, 0, 0, 0,
|
||||||
new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b),
|
new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b),
|
||||||
(float) dist * 3f));
|
(float) dist * 3f));
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ package com.volmit.iris.engine;
|
|||||||
import com.google.common.util.concurrent.AtomicDouble;
|
import com.google.common.util.concurrent.AtomicDouble;
|
||||||
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.core.ServerConfigurator;
|
|
||||||
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
import com.volmit.iris.core.nms.container.BlockPos;
|
import com.volmit.iris.core.nms.container.BlockPos;
|
||||||
@@ -53,7 +51,6 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
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;
|
||||||
@@ -66,8 +63,6 @@ import java.util.Set;
|
|||||||
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.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(exclude = "context")
|
@EqualsAndHashCode(exclude = "context")
|
||||||
@@ -242,11 +237,6 @@ public class IrisEngine implements Engine {
|
|||||||
getTarget().setDimension(getData().getDimensionLoader().load(getDimension().getLoadKey()));
|
getTarget().setDimension(getData().getDimensionLoader().load(getDimension().getLoadKey()));
|
||||||
prehotload();
|
prehotload();
|
||||||
setupEngine();
|
setupEngine();
|
||||||
J.a(() -> {
|
|
||||||
synchronized (ServerConfigurator.class) {
|
|
||||||
ServerConfigurator.installDataPacks(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
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;
|
||||||
@@ -68,8 +69,10 @@ public class IrisBiomeCustom {
|
|||||||
@Desc("The biome's category type")
|
@Desc("The biome's category type")
|
||||||
private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains;
|
private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains;
|
||||||
|
|
||||||
|
@MinNumber(0)
|
||||||
|
@MaxNumber(20)
|
||||||
@Desc("The spawn rarity of any defined spawners")
|
@Desc("The spawn rarity of any defined spawners")
|
||||||
private int spawnRarity = -1;
|
private int spawnRarity = 0;
|
||||||
|
|
||||||
@Desc("The color of the sky, top half of sky. (hex format)")
|
@Desc("The color of the sky, top half of sky. (hex format)")
|
||||||
private String skyColor = "#79a8e1";
|
private String skyColor = "#79a8e1";
|
||||||
@@ -155,7 +158,7 @@ public class IrisBiomeCustom {
|
|||||||
j.put("spawners", spawners);
|
j.put("spawners", spawners);
|
||||||
}
|
}
|
||||||
|
|
||||||
return j.toString(4);
|
return DataVersion.getDefault().fixCustomBiome(this, j).toString(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int parseColor(String c) {
|
private int parseColor(String c) {
|
||||||
|
|||||||
@@ -18,17 +18,12 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
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.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
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.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.data.Dimension;
|
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
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;
|
||||||
@@ -43,10 +38,6 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -380,56 +371,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
return landBiomeStyle;
|
return landBiomeStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean installDataPack(DataProvider data, File datapacks) {
|
|
||||||
boolean write = false;
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
IO.delete(new File(datapacks, "iris/data/" + getLoadKey().toLowerCase()));
|
|
||||||
|
|
||||||
for (IrisBiome i : getAllBiomes(data)) {
|
|
||||||
if (i.isCustom()) {
|
|
||||||
write = true;
|
|
||||||
|
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
|
||||||
File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json");
|
|
||||||
|
|
||||||
if (!output.exists()) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
|
|
||||||
output.getParentFile().mkdirs();
|
|
||||||
try {
|
|
||||||
IO.writeAll(output, j.generateJson());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
File mcm = new File(datapacks, "iris/pack.mcmeta");
|
|
||||||
try {
|
|
||||||
IO.writeAll(mcm, """
|
|
||||||
{
|
|
||||||
"pack": {
|
|
||||||
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
|
||||||
"pack_format": 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFolderName() {
|
public String getFolderName() {
|
||||||
return "dimensions";
|
return "dimensions";
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.volmit.iris.util.format.C;
|
|||||||
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.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.plugin.Chunks;
|
import com.volmit.iris.util.plugin.Chunks;
|
||||||
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;
|
||||||
@@ -65,6 +66,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class IrisEntity extends IrisRegistrant {
|
public class IrisEntity extends IrisRegistrant {
|
||||||
|
private static final Particle ITEM = E.getOrDefault(Particle.class, "ITEM_CRACK", "ITEM");
|
||||||
@Required
|
@Required
|
||||||
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
|
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
|
||||||
private EntityType type = EntityType.UNKNOWN;
|
private EntityType type = EntityType.UNKNOWN;
|
||||||
@@ -386,7 +388,7 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
|
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
|
||||||
e.teleport(start.add(new Vector(0, 0.1, 0)));
|
e.teleport(start.add(new Vector(0, 0.1, 0)));
|
||||||
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
|
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
|
||||||
e.getWorld().spawnParticle(Particle.ITEM_CRACK, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
|
e.getWorld().spawnParticle(ITEM, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
|
||||||
if (M.r(0.2)) {
|
if (M.r(0.2)) {
|
||||||
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
|
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.volmit.iris.core.service.ExternalDataSVC;
|
|||||||
import com.volmit.iris.engine.object.IrisCompat;
|
import com.volmit.iris.engine.object.IrisCompat;
|
||||||
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.misc.E;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -46,6 +47,7 @@ public class B {
|
|||||||
private static final KMap<String, BlockData> custom = new KMap<>();
|
private static final KMap<String, BlockData> custom = new KMap<>();
|
||||||
|
|
||||||
private static final Material AIR_MATERIAL = Material.AIR;
|
private static final Material AIR_MATERIAL = Material.AIR;
|
||||||
|
private static final Material SHORT_GRASS = E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS");
|
||||||
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
||||||
private static final IntSet foliageCache = buildFoliageCache();
|
private static final IntSet foliageCache = buildFoliageCache();
|
||||||
private static final IntSet deepslateCache = buildDeepslateCache();
|
private static final IntSet deepslateCache = buildDeepslateCache();
|
||||||
@@ -85,7 +87,7 @@ public class B {
|
|||||||
WHITE_TULIP,
|
WHITE_TULIP,
|
||||||
FERN,
|
FERN,
|
||||||
LARGE_FERN,
|
LARGE_FERN,
|
||||||
GRASS,
|
SHORT_GRASS,
|
||||||
TALL_GRASS
|
TALL_GRASS
|
||||||
}).forEach((i) -> b.add(i.ordinal()));
|
}).forEach((i) -> b.add(i.ordinal()));
|
||||||
|
|
||||||
@@ -143,7 +145,7 @@ public class B {
|
|||||||
private static IntSet buildDecorantCache() {
|
private static IntSet buildDecorantCache() {
|
||||||
IntSet b = new IntOpenHashSet();
|
IntSet b = new IntOpenHashSet();
|
||||||
Arrays.stream(new Material[]{
|
Arrays.stream(new Material[]{
|
||||||
GRASS,
|
SHORT_GRASS,
|
||||||
TALL_GRASS,
|
TALL_GRASS,
|
||||||
TALL_SEAGRASS,
|
TALL_SEAGRASS,
|
||||||
FERN,
|
FERN,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisBlockData implements BlockData{
|
public class IrisBlockData implements BlockData {
|
||||||
private final @NonNull BlockData base;
|
private final @NonNull BlockData base;
|
||||||
private final @NotNull Identifier custom;
|
private final @NotNull Identifier custom;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.volmit.iris.util.decree.handlers;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.decree.DecreeParameterHandler;
|
||||||
|
import com.volmit.iris.util.decree.exceptions.DecreeParsingException;
|
||||||
|
|
||||||
|
public class DataVersionHandler implements DecreeParameterHandler<DataVersion> {
|
||||||
|
@Override
|
||||||
|
public KList<DataVersion> getPossibilities() {
|
||||||
|
return new KList<>(DataVersion.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(DataVersion version) {
|
||||||
|
return version.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataVersion parse(String in, boolean force) throws DecreeParsingException {
|
||||||
|
if (in.equalsIgnoreCase("latest")) {
|
||||||
|
return DataVersion.getLatest();
|
||||||
|
}
|
||||||
|
for (DataVersion v : DataVersion.values()) {
|
||||||
|
if (v.getVersion().equalsIgnoreCase(in)) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new DecreeParsingException("Unable to parse data version \"" + in + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> type) {
|
||||||
|
return DataVersion.class.equals(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -212,7 +212,7 @@ public class UIElement implements Element {
|
|||||||
im.setLore(getLore().copy());
|
im.setLore(getLore().copy());
|
||||||
|
|
||||||
if (isEnchanted()) {
|
if (isEnchanted()) {
|
||||||
im.addEnchant(Enchantment.DURABILITY, 1, true);
|
im.addEnchant(Enchantment.FIRE_ASPECT, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
is.setItemMeta(im);
|
is.setItemMeta(im);
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.volmit.iris.util.misc;
|
||||||
|
|
||||||
|
public class E {
|
||||||
|
|
||||||
|
public static <T extends Enum<T>> T getOrDefault(Class<T> enumClass, String name, String fallback) {
|
||||||
|
try {
|
||||||
|
return Enum.valueOf(enumClass, name);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return Enum.valueOf(enumClass, fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
+25
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R1;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -11,6 +12,7 @@ import com.volmit.iris.util.math.RNG;
|
|||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
@@ -25,6 +27,7 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CustomBiomeSource extends BiomeSource {
|
public class CustomBiomeSource extends BiomeSource {
|
||||||
private final long seed;
|
private final long seed;
|
||||||
@@ -118,8 +121,28 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ResourceKey<Biome> biomeKey = optionalBiomeKey.get();
|
||||||
|
Optional<Holder<Biome>> optionalReferenceHolder = customRegistry.getHolder(biomeKey);
|
||||||
|
if (optionalReferenceHolder.isEmpty()) {
|
||||||
|
Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m.put(j.getId(), optionalReferenceHolder.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
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.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -587,51 +584,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registry.BIOME_REGISTRY, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registry.BIOME_REGISTRY, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+25
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R2;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -12,6 +13,7 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
@@ -26,6 +28,7 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CustomBiomeSource extends BiomeSource {
|
public class CustomBiomeSource extends BiomeSource {
|
||||||
|
|
||||||
@@ -120,8 +123,28 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ResourceKey<Biome> biomeKey = optionalBiomeKey.get();
|
||||||
|
Optional<Holder.Reference<Biome>> optionalReferenceHolder = customRegistry.getHolder(biomeKey);
|
||||||
|
if (optionalReferenceHolder.isEmpty()) {
|
||||||
|
Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m.put(j.getId(), optionalReferenceHolder.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
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.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -589,51 +586,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+11
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R3;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
Biome biome = customRegistry.get(resourceLocation);
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
if (optionalBiomeKey.isEmpty()) {
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
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.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -593,51 +590,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+11
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R1;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
Biome biome = customRegistry.get(resourceLocation);
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
if (optionalBiomeKey.isEmpty()) {
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.nms.INMSBinding;
|
import com.volmit.iris.core.nms.INMSBinding;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
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.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.format.C;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
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;
|
||||||
@@ -47,7 +47,6 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
import net.minecraft.util.GsonHelper;
|
import net.minecraft.util.GsonHelper;
|
||||||
import net.minecraft.world.RandomSequences;
|
import net.minecraft.world.RandomSequences;
|
||||||
import net.minecraft.world.entity.EntityDimensions;
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
@@ -73,9 +72,7 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
|
|||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Dolphin;
|
import org.bukkit.entity.Dolphin;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.generator.BiomeProvider;
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -87,12 +84,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -580,51 +574,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+11
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R2;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
Biome biome = customRegistry.get(resourceLocation);
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
if (optionalBiomeKey.isEmpty()) {
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
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.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -590,51 +587,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+11
-2
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R3;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource {
|
|||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
Biome biome = customRegistry.get(resourceLocation);
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
if (optionalBiomeKey.isEmpty()) {
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
|||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final RegionFileStorage storage;
|
private final RegionFileStorage storage;
|
||||||
private final Queue<ProtoChunk> chunkQueue = new ArrayDeque<>();
|
private final Queue<ProtoChunk> chunkQueue = new ArrayDeque<>();
|
||||||
private final ReentrantLock manualLock = new ReentrantLock();
|
private final ReentrantLock saveLock = new ReentrantLock();
|
||||||
private final KMap<String, Holder<Biome>> customBiomes = new KMap<>();
|
private final KMap<String, Holder<Biome>> customBiomes = new KMap<>();
|
||||||
private final KMap<NamespacedKey, Holder<Biome>> minecraftBiomes = new KMap<>();
|
private final KMap<NamespacedKey, Holder<Biome>> minecraftBiomes = new KMap<>();
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
@@ -60,40 +60,38 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
|||||||
var queueLooper = new Looper() {
|
var queueLooper = new Looper() {
|
||||||
@Override
|
@Override
|
||||||
protected long loop() {
|
protected long loop() {
|
||||||
if (manualLock.isLocked()) {
|
save();
|
||||||
manualLock.lock();
|
|
||||||
manualLock.unlock();
|
|
||||||
}
|
|
||||||
saveAll();
|
|
||||||
return closed ? -1 : 100;
|
return closed ? -1 : 100;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
queueLooper.setName("Region Save Looper");
|
queueLooper.setName("Region Save Looper");
|
||||||
queueLooper.start();
|
queueLooper.start();
|
||||||
|
|
||||||
|
var dimKey = engine.getDimension().getLoadKey();
|
||||||
|
for (var biome : engine.getAllBiomes()) {
|
||||||
|
if (!biome.isCustom()) continue;
|
||||||
|
for (var custom : biome.getCustomDerivitives()) {
|
||||||
|
binding.registerBiome(dimKey, custom, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean exists(int x, int z) {
|
public boolean exists(int x, int z) {
|
||||||
if (closed) return false;
|
if (closed) return false;
|
||||||
try {
|
try {
|
||||||
return storage.getRegionFile(new ChunkPos(x << 5, z << 5), true) != null;
|
CompoundTag tag = storage.read(new ChunkPos(x, z));
|
||||||
|
return tag != null && !"empty".equals(tag.getString("Status"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAll() {
|
public void save() {
|
||||||
manualLock.lock();
|
|
||||||
try {
|
|
||||||
save();
|
|
||||||
} finally {
|
|
||||||
manualLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void save() {
|
|
||||||
if (closed) return;
|
if (closed) return;
|
||||||
|
saveLock.lock();
|
||||||
|
try {
|
||||||
while (!chunkQueue.isEmpty()) {
|
while (!chunkQueue.isEmpty()) {
|
||||||
ChunkAccess chunk = chunkQueue.poll();
|
ChunkAccess chunk = chunkQueue.poll();
|
||||||
if (chunk == null) break;
|
if (chunk == null) break;
|
||||||
@@ -104,6 +102,9 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
saveLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,16 +138,9 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateChunk(int x, int z) {
|
public void generateChunk(int x, int z) {
|
||||||
if (closed) return;
|
if (closed || exists(x, z)) return;
|
||||||
try {
|
try {
|
||||||
var pos = new ChunkPos(x, z);
|
var pos = new ChunkPos(x, z);
|
||||||
try {
|
|
||||||
CompoundTag tag = storage.read(pos);
|
|
||||||
if (tag != null && !"empty".equals(tag.getString("Status"))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
|
|
||||||
ProtoChunk chunk = binding.createProtoChunk(pos, this);
|
ProtoChunk chunk = binding.createProtoChunk(pos, this);
|
||||||
var tc = new MCATerrainChunk(chunk);
|
var tc = new MCATerrainChunk(chunk);
|
||||||
|
|
||||||
@@ -190,7 +184,7 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
|||||||
IrisContext.getOr(engine).setChunkContext(ctx);
|
IrisContext.getOr(engine).setChunkContext(ctx);
|
||||||
|
|
||||||
for (EngineStage i : engine.getMode().getStages()) {
|
for (EngineStage i : engine.getMode().getStages()) {
|
||||||
i.generate(x, z, blocks, vbiomes, true, ctx);
|
i.generate(x, z, blocks, vbiomes, false, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -23,16 +21,9 @@ import com.mojang.serialization.JsonOps;
|
|||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import com.volmit.iris.core.nms.IHeadless;
|
import com.volmit.iris.core.nms.IHeadless;
|
||||||
import com.volmit.iris.core.nms.v1_20_R3.mca.ChunkSerializer;
|
import com.volmit.iris.core.nms.v1_20_R3.mca.ChunkSerializer;
|
||||||
import com.volmit.iris.core.nms.v1_20_R3.mca.MCATerrainChunk;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
import com.volmit.iris.core.nms.v1_20_R3.mca.RegionFileStorage;
|
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
|
|
||||||
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
|
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -601,51 +592,10 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean loadDatapack(File folder, boolean replace) {
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
var data = new File(folder, "iris/data");
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
if (!data.exists() || !data.isDirectory()) return false;
|
if (biomeBase == null) return false;
|
||||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
|
||||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
||||||
if (files == null) return false;
|
|
||||||
for (File file : files) {
|
|
||||||
var biome = new File(file, "worldgen/biome");
|
|
||||||
if (!biome.exists()) continue;
|
|
||||||
var biomeFiles = biome.listFiles(jsonFilter);
|
|
||||||
if (biomeFiles == null) continue;
|
|
||||||
for (File biomeFile : biomeFiles) {
|
|
||||||
String json = null;
|
|
||||||
int tries = 10;
|
|
||||||
while (json == null && tries-- > 0) {
|
|
||||||
try {
|
|
||||||
json = IO.readAll(biomeFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
|
||||||
if (tries == 0) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (json == null) continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
|
||||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceLocation from(String namespace, File file) {
|
|
||||||
var name = file.getName();
|
|
||||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
|||||||
+10
-7
@@ -42,6 +42,9 @@ public record MCATerrainChunk(ChunkAccess chunk) implements TerrainChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBiome(int x, int y, int z, Biome bio) {
|
public void setBiome(int x, int y, int z, Biome bio) {
|
||||||
|
if (y < 0) return;
|
||||||
|
y += getMinHeight();
|
||||||
|
if (y > getMaxHeight()) return;
|
||||||
chunk.setBiome(x & 15, y, z & 15, CraftBiome.bukkitToMinecraftHolder(bio));
|
chunk.setBiome(x & 15, y, z & 15, CraftBiome.bukkitToMinecraftHolder(bio));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +64,9 @@ public record MCATerrainChunk(ChunkAccess chunk) implements TerrainChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(int x, int y, int z, BlockData blockData) {
|
public void setBlock(int x, int y, int z, BlockData blockData) {
|
||||||
if (y > getMaxHeight() || y < getMinHeight()) {
|
if (y < 0) return;
|
||||||
return;
|
y += getMinHeight();
|
||||||
}
|
if (y > getMaxHeight()) return;
|
||||||
|
|
||||||
if (blockData == null) {
|
if (blockData == null) {
|
||||||
Iris.error("NULL BD");
|
Iris.error("NULL BD");
|
||||||
@@ -76,14 +79,14 @@ public record MCATerrainChunk(ChunkAccess chunk) implements TerrainChunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BlockState getBlockState(int x, int y, int z) {
|
private BlockState getBlockState(int x, int y, int z) {
|
||||||
|
if (y < 0) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
y += getMinHeight();
|
||||||
if (y > getMaxHeight()) {
|
if (y > getMaxHeight()) {
|
||||||
y = getMaxHeight();
|
y = getMaxHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y < getMinHeight()) {
|
|
||||||
y = getMinHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunk.getBlockState(new BlockPos(x & 15, y, z & 15));
|
return chunk.getBlockState(new BlockPos(x & 15, y, z & 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
package com.volmit.iris.core.nms.v1_20_R4;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.Climate;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class CustomBiomeSource extends BiomeSource {
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
private final Engine engine;
|
||||||
|
private final Registry<Biome> biomeCustomRegistry;
|
||||||
|
private final Registry<Biome> biomeRegistry;
|
||||||
|
private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>();
|
||||||
|
private final RNG rng;
|
||||||
|
private final KMap<String, Holder<Biome>> customBiomes;
|
||||||
|
|
||||||
|
public CustomBiomeSource(long seed, Engine engine, World world) {
|
||||||
|
this.engine = engine;
|
||||||
|
this.seed = seed;
|
||||||
|
this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null);
|
||||||
|
this.biomeRegistry = ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())).registry(Registries.BIOME).orElse(null);
|
||||||
|
this.rng = new RNG(engine.getSeedManager().getBiome());
|
||||||
|
this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Holder<Biome>> getAllBiomes(Registry<Biome> customRegistry, Registry<Biome> registry, Engine engine) {
|
||||||
|
List<Holder<Biome>> b = new ArrayList<>();
|
||||||
|
|
||||||
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
|
if (i.isCustom()) {
|
||||||
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
|
b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
|
||||||
|
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.add(NMSBinding.biomeToBiomeBase(registry, i.getVanillaDerivative()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getFor(Class<?> type, Object source) {
|
||||||
|
Object o = fieldFor(type, source);
|
||||||
|
|
||||||
|
if (o != null) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
return invokeFor(type, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object fieldFor(Class<?> returns, Object in) {
|
||||||
|
return fieldForClass(returns, in.getClass(), in);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object invokeFor(Class<?> returns, Object in) {
|
||||||
|
for (Method i : in.getClass().getMethods()) {
|
||||||
|
if (i.getReturnType().equals(returns)) {
|
||||||
|
i.setAccessible(true);
|
||||||
|
try {
|
||||||
|
Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
|
||||||
|
return i.invoke(in);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> T fieldForClass(Class<T> returnType, Class<?> sourceType, Object in) {
|
||||||
|
for (Field i : sourceType.getDeclaredFields()) {
|
||||||
|
if (i.getType().equals(returnType)) {
|
||||||
|
i.setAccessible(true);
|
||||||
|
try {
|
||||||
|
Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
|
||||||
|
return (T) i.get(in);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||||
|
return getAllBiomes(
|
||||||
|
((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()))
|
||||||
|
.registry(Registries.BIOME).orElse(null),
|
||||||
|
((CraftWorld) engine.getWorld().realWorld()).getHandle().registryAccess().registry(Registries.BIOME).orElse(null),
|
||||||
|
engine).stream();
|
||||||
|
}
|
||||||
|
private KMap<String, Holder<Biome>> fillCustomBiomes(Registry<Biome> customRegistry, Engine engine) {
|
||||||
|
KMap<String, Holder<Biome>> m = new KMap<>();
|
||||||
|
|
||||||
|
for (IrisBiome i : engine.getAllBiomes()) {
|
||||||
|
if (i.isCustom()) {
|
||||||
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
|
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||||
|
Biome biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||||
|
biome = customRegistry.get(location);
|
||||||
|
if (biome == null) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||||
|
if (optionalBiomeKey.isEmpty()) {
|
||||||
|
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ResourceKey<Biome> biomeKey = optionalBiomeKey.get();
|
||||||
|
Optional<Holder.Reference<Biome>> optionalReferenceHolder = customRegistry.getHolder(biomeKey);
|
||||||
|
if (optionalReferenceHolder.isEmpty()) {
|
||||||
|
Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m.put(j.getId(), optionalReferenceHolder.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegistryAccess registry() {
|
||||||
|
return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MapCodec<? extends BiomeSource> codec() {
|
||||||
|
throw new UnsupportedOperationException("Not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
|
||||||
|
int m = (y - engine.getMinHeight()) << 2;
|
||||||
|
IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2);
|
||||||
|
if (ib.isCustom()) {
|
||||||
|
return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId());
|
||||||
|
} else {
|
||||||
|
org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2);
|
||||||
|
return NMSBinding.biomeToBiomeBase(biomeRegistry, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,767 @@
|
|||||||
|
package com.volmit.iris.core.nms.v1_20_R4;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
|
||||||
|
import net.bytebuddy.matcher.ElementMatchers;
|
||||||
|
import net.minecraft.core.MappedRegistry;
|
||||||
|
import net.minecraft.core.RegistrationInfo;
|
||||||
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
|
import net.minecraft.util.GsonHelper;
|
||||||
|
import net.minecraft.world.RandomSequences;
|
||||||
|
import net.minecraft.world.item.component.CustomData;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.level.dimension.LevelStem;
|
||||||
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.CraftChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftDolphin;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R4.util.CraftNamespacedKey;
|
||||||
|
import org.bukkit.entity.Dolphin;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMSBinding;
|
||||||
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
|
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.hunk.Hunk;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.math.Vector3d;
|
||||||
|
import com.volmit.iris.util.matter.MatterBiomeInject;
|
||||||
|
import com.volmit.iris.util.nbt.io.NBTUtil;
|
||||||
|
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||||
|
import com.volmit.iris.util.nbt.mca.palette.*;
|
||||||
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.nbt.NbtIo;
|
||||||
|
import net.minecraft.nbt.TagParser;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
public class NMSBinding implements INMSBinding {
|
||||||
|
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
|
||||||
|
private final BlockData AIR = Material.AIR.createBlockData();
|
||||||
|
private final AtomicCache<MCAIdMap<net.minecraft.world.level.biome.Biome>> biomeMapCache = new AtomicCache<>();
|
||||||
|
private final AtomicCache<MCAIdMapper<BlockState>> registryCache = new AtomicCache<>();
|
||||||
|
private final AtomicCache<MCAPalette<BlockState>> globalCache = new AtomicCache<>();
|
||||||
|
private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>();
|
||||||
|
private final AtomicCache<Method> byIdRef = new AtomicCache<>();
|
||||||
|
private Field biomeStorageCache = null;
|
||||||
|
|
||||||
|
private static Object getFor(Class<?> type, Object source) {
|
||||||
|
Object o = fieldFor(type, source);
|
||||||
|
|
||||||
|
if (o != null) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
return invokeFor(type, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object invokeFor(Class<?> returns, Object in) {
|
||||||
|
for (Method i : in.getClass().getMethods()) {
|
||||||
|
if (i.getReturnType().equals(returns)) {
|
||||||
|
i.setAccessible(true);
|
||||||
|
try {
|
||||||
|
Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
|
||||||
|
return i.invoke(in);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object fieldFor(Class<?> returns, Object in) {
|
||||||
|
return fieldForClass(returns, in.getClass(), in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> T fieldForClass(Class<T> returnType, Class<?> sourceType, Object in) {
|
||||||
|
for (Field i : sourceType.getDeclaredFields()) {
|
||||||
|
if (i.getType().equals(returnType)) {
|
||||||
|
i.setAccessible(true);
|
||||||
|
try {
|
||||||
|
Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
|
||||||
|
return (T) i.get(in);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> getClassType(Class<?> type, int ordinal) {
|
||||||
|
return type.getDeclaredClasses()[ordinal];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Location l) {
|
||||||
|
return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag serializeTile(Location location) {
|
||||||
|
BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true);
|
||||||
|
|
||||||
|
if (e == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry());
|
||||||
|
return convert(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(boas);
|
||||||
|
tag.write(dos);
|
||||||
|
dos.close();
|
||||||
|
return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||||
|
NBTUtil.write(tag, boas, false);
|
||||||
|
DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray()));
|
||||||
|
net.minecraft.nbt.CompoundTag c = NbtIo.read(din);
|
||||||
|
din.close();
|
||||||
|
return c;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserializeTile(CompoundTag c, Location pos) {
|
||||||
|
((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag serializeEntity(Entity location) {
|
||||||
|
return null;// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity deserializeEntity(CompoundTag s, Location newPosition) {
|
||||||
|
return null;// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsCustomHeight() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegistryAccess registry() {
|
||||||
|
return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Registry<net.minecraft.world.level.biome.Biome> getCustomBiomeRegistry() {
|
||||||
|
return registry().registry(Registries.BIOME).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Registry<Block> getBlockRegistry() {
|
||||||
|
return registry().registry(Registries.BLOCK).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getBiomeBaseFromId(int id) {
|
||||||
|
return getCustomBiomeRegistry().getHolder(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight(World world) {
|
||||||
|
return world.getMinHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsCustomBiomes() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTrueBiomeBaseId(Object biomeBase) {
|
||||||
|
return getCustomBiomeRegistry().getId(((Holder<net.minecraft.world.level.biome.Biome>) biomeBase).value());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getTrueBiomeBase(Location location) {
|
||||||
|
return ((CraftWorld) location.getWorld()).getHandle().getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTrueBiomeBaseKey(Location location) {
|
||||||
|
return getKeyForBiomeBase(getTrueBiomeBase(location));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCustomBiomeBaseFor(String mckey) {
|
||||||
|
return getCustomBiomeRegistry().get(new ResourceLocation(mckey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCustomBiomeBaseHolderFor(String mckey) {
|
||||||
|
return getCustomBiomeRegistry().getHolder(getTrueBiomeBaseId(getCustomBiomeRegistry().get(new ResourceLocation(mckey)))).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBiomeBaseIdForKey(String key) {
|
||||||
|
return getCustomBiomeRegistry().getId(getCustomBiomeRegistry().get(new ResourceLocation(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKeyForBiomeBase(Object biomeBase) {
|
||||||
|
return getCustomBiomeRegistry().getKey((net.minecraft.world.level.biome.Biome) biomeBase).getPath(); // something, not something:something
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getBiomeBase(World world, Biome biome) {
|
||||||
|
return biomeToBiomeBase(((CraftWorld) world).getHandle()
|
||||||
|
.registryAccess().registry(Registries.BIOME).orElse(null), biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getBiomeBase(Object registry, Biome biome) {
|
||||||
|
Object v = baseBiomeCache.get(biome);
|
||||||
|
|
||||||
|
if (v != null) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
//noinspection unchecked
|
||||||
|
v = biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, biome);
|
||||||
|
if (v == null) {
|
||||||
|
// Ok so there is this new biome name called "CUSTOM" in Paper's new releases.
|
||||||
|
// But, this does NOT exist within CraftBukkit which makes it return an error.
|
||||||
|
// So, we will just return the ID that the plains biome returns instead.
|
||||||
|
//noinspection unchecked
|
||||||
|
return biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, Biome.PLAINS);
|
||||||
|
}
|
||||||
|
baseBiomeCache.put(biome, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KList<Biome> getBiomes() {
|
||||||
|
return new KList<>(Biome.values()).qadd(Biome.CHERRY_GROVE).qdel(Biome.CUSTOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBukkit() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBiomeId(Biome biome) {
|
||||||
|
for (World i : Bukkit.getWorlds()) {
|
||||||
|
if (i.getEnvironment().equals(World.Environment.NORMAL)) {
|
||||||
|
Registry<net.minecraft.world.level.biome.Biome> registry = ((CraftWorld) i).getHandle().registryAccess().registry(Registries.BIOME).orElse(null);
|
||||||
|
return registry.getId((net.minecraft.world.level.biome.Biome) getBiomeBase(registry, biome));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return biome.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MCAIdMap<net.minecraft.world.level.biome.Biome> getBiomeMapping() {
|
||||||
|
return biomeMapCache.aquire(() -> new MCAIdMap<>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<net.minecraft.world.level.biome.Biome> iterator() {
|
||||||
|
return getCustomBiomeRegistry().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId(net.minecraft.world.level.biome.Biome paramT) {
|
||||||
|
return getCustomBiomeRegistry().getId(paramT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.biome.Biome byId(int paramInt) {
|
||||||
|
return (net.minecraft.world.level.biome.Biome) getBiomeBaseFromId(paramInt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private MCABiomeContainer getBiomeContainerInterface(MCAIdMap<net.minecraft.world.level.biome.Biome> biomeMapping, MCAChunkBiomeContainer<net.minecraft.world.level.biome.Biome> base) {
|
||||||
|
return new MCABiomeContainer() {
|
||||||
|
@Override
|
||||||
|
public int[] getData() {
|
||||||
|
return base.writeBiomes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBiome(int x, int y, int z, int id) {
|
||||||
|
base.setBiome(x, y, z, biomeMapping.byId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBiome(int x, int y, int z) {
|
||||||
|
return biomeMapping.getId(base.getBiome(x, y, z));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MCABiomeContainer newBiomeContainer(int min, int max) {
|
||||||
|
MCAChunkBiomeContainer<net.minecraft.world.level.biome.Biome> base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max);
|
||||||
|
return getBiomeContainerInterface(getBiomeMapping(), base);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) {
|
||||||
|
MCAChunkBiomeContainer<net.minecraft.world.level.biome.Biome> base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data);
|
||||||
|
return getBiomeContainerInterface(getBiomeMapping(), base);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countCustomBiomes() {
|
||||||
|
AtomicInteger a = new AtomicInteger(0);
|
||||||
|
|
||||||
|
getCustomBiomeRegistry().keySet().forEach((i) -> {
|
||||||
|
if (i.getNamespace().equals("minecraft")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.incrementAndGet();
|
||||||
|
Iris.debug("Custom Biome: " + i);
|
||||||
|
});
|
||||||
|
|
||||||
|
return a.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsDataPacks() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBiomes(int cx, int cz, World world, Hunk<Object> biomes) {
|
||||||
|
LevelChunk c = ((CraftWorld) world).getHandle().getChunk(cx, cz);
|
||||||
|
biomes.iterateSync((x, y, z, b) -> c.setBiome(x, y, z, (Holder<net.minecraft.world.level.biome.Biome>) b));
|
||||||
|
c.setUnsaved(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) {
|
||||||
|
try {
|
||||||
|
ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk);
|
||||||
|
Holder<net.minecraft.world.level.biome.Biome> biome = (Holder<net.minecraft.world.level.biome.Biome>) somethingVeryDirty;
|
||||||
|
s.setBiome(x, y, z, biome);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Field getFieldForBiomeStorage(Object storage) {
|
||||||
|
Field f = biomeStorageCache;
|
||||||
|
|
||||||
|
if (f != null) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f = storage.getClass().getDeclaredField("biome");
|
||||||
|
f.setAccessible(true);
|
||||||
|
return f;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
Iris.error(storage.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
biomeStorageCache = f;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MCAPaletteAccess createPalette() {
|
||||||
|
MCAIdMapper<BlockState> registry = registryCache.aquireNasty(() -> {
|
||||||
|
Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId");
|
||||||
|
Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT");
|
||||||
|
Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId");
|
||||||
|
cf.setAccessible(true);
|
||||||
|
df.setAccessible(true);
|
||||||
|
bf.setAccessible(true);
|
||||||
|
net.minecraft.core.IdMapper<BlockState> blockData = Block.BLOCK_STATE_REGISTRY;
|
||||||
|
int b = bf.getInt(blockData);
|
||||||
|
Object2IntMap<BlockState> c = (Object2IntMap<BlockState>) cf.get(blockData);
|
||||||
|
List<BlockState> d = (List<BlockState>) df.get(blockData);
|
||||||
|
return new MCAIdMapper<BlockState>(c, d, b);
|
||||||
|
});
|
||||||
|
MCAPalette<BlockState> global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState()));
|
||||||
|
MCAPalettedContainer<BlockState> container = new MCAPalettedContainer<>(global, registry,
|
||||||
|
i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(),
|
||||||
|
i -> NBTWorld.getCompound(CraftBlockData.fromData(i)),
|
||||||
|
((CraftBlockData) AIR).getState());
|
||||||
|
return new MCAWrappedPalettedContainer<>(container,
|
||||||
|
i -> NBTWorld.getCompound(CraftBlockData.fromData(i)),
|
||||||
|
i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectBiomesFromMantle(Chunk e, Mantle mantle) {
|
||||||
|
ChunkAccess chunk = ((CraftChunk) e).getHandle(ChunkStatus.FULL);
|
||||||
|
AtomicInteger c = new AtomicInteger();
|
||||||
|
AtomicInteger r = new AtomicInteger();
|
||||||
|
mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x, y, z, b) -> {
|
||||||
|
if (b != null) {
|
||||||
|
if (b.isCustom()) {
|
||||||
|
chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get());
|
||||||
|
c.getAndIncrement();
|
||||||
|
} else {
|
||||||
|
chunk.setBiome(x, y, z, (Holder<net.minecraft.world.level.biome.Biome>) getBiomeBase(e.getWorld(), b.getBiome()));
|
||||||
|
r.getAndIncrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException {
|
||||||
|
if (customNbt != null && !customNbt.isEmpty()) {
|
||||||
|
net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(itemStack);
|
||||||
|
|
||||||
|
try {
|
||||||
|
net.minecraft.nbt.CompoundTag tag = TagParser.parseTag((new JSONObject(customNbt)).toString());
|
||||||
|
tag.merge(s.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).getUnsafe());
|
||||||
|
s.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
||||||
|
} catch (CommandSyntaxException var5) {
|
||||||
|
throw new IllegalArgumentException(var5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CraftItemStack.asBukkitCopy(s);
|
||||||
|
} else {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos) {
|
||||||
|
CraftDolphin cd = (CraftDolphin)dolphin;
|
||||||
|
cd.getHandle().setTreasurePos(new BlockPos(pos.getX(), pos.getY(), pos.getZ()));
|
||||||
|
cd.getHandle().setGotFish(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
ServerLevel serverLevel = ((CraftWorld)world).getHandle();
|
||||||
|
Class<?> clazz = serverLevel.getChunkSource().chunkMap.generator.getClass();
|
||||||
|
Field biomeSource = getField(clazz, BiomeSource.class);
|
||||||
|
biomeSource.setAccessible(true);
|
||||||
|
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
unsafeField.setAccessible(true);
|
||||||
|
Unsafe unsafe = (Unsafe)unsafeField.get(null);
|
||||||
|
CustomBiomeSource customBiomeSource = new CustomBiomeSource(seed, engine, world);
|
||||||
|
unsafe.putObject(biomeSource.get(serverLevel.getChunkSource().chunkMap.generator), unsafe.objectFieldOffset(biomeSource), customBiomeSource);
|
||||||
|
biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
|
||||||
|
Field[] fields = EntityType.class.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) {
|
||||||
|
try {
|
||||||
|
EntityType entityType = (EntityType) field.get(null);
|
||||||
|
if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) {
|
||||||
|
Vector<Float> v1 = new Vector<>();
|
||||||
|
v1.add(entityType.getHeight());
|
||||||
|
entityType.getDimensions();
|
||||||
|
Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
||||||
|
//System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width);
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Iris.error("Unable to get entity dimensions!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) {
|
||||||
|
return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field getField(Class<?> clazz, Class<?> fieldType) throws NoSuchFieldException {
|
||||||
|
try {
|
||||||
|
for (Field f : clazz.getDeclaredFields()) {
|
||||||
|
if (f.getType().equals(fieldType))
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(fieldType.getName());
|
||||||
|
} catch (NoSuchFieldException var4) {
|
||||||
|
Class<?> superClass = clazz.getSuperclass();
|
||||||
|
if (superClass == null) {
|
||||||
|
throw var4;
|
||||||
|
} else {
|
||||||
|
return getField(superClass, fieldType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Holder<net.minecraft.world.level.biome.Biome> biomeToBiomeBase(Registry<net.minecraft.world.level.biome.Biome> registry, Biome biome) {
|
||||||
|
return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataVersion getDataVersion() {
|
||||||
|
return DataVersion.V1205;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerDimension(String name, IrisDimension dimension) {
|
||||||
|
var registry = registry(Registries.DIMENSION_TYPE);
|
||||||
|
var baseLocation = switch (dimension.getEnvironment()) {
|
||||||
|
case NORMAL -> new ResourceLocation("minecraft", "overworld");
|
||||||
|
case NETHER -> new ResourceLocation("minecraft", "the_nether");
|
||||||
|
case THE_END -> new ResourceLocation("minecraft", "the_end");
|
||||||
|
case CUSTOM -> throw new IllegalArgumentException("Cannot register custom dimension");
|
||||||
|
};
|
||||||
|
var base = registry.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, baseLocation)).orElse(null);
|
||||||
|
if (base == null) return false;
|
||||||
|
var json = encode(DimensionType.CODEC, base).orElse(null);
|
||||||
|
if (json == null) return false;
|
||||||
|
var object = json.getAsJsonObject();
|
||||||
|
var height = dimension.getDimensionHeight();
|
||||||
|
object.addProperty("min_y", height.getMin());
|
||||||
|
object.addProperty("height", height.getMax() - height.getMin());
|
||||||
|
object.addProperty("logical_height", dimension.getLogicalHeight());
|
||||||
|
var value = decode(DimensionType.CODEC, object.toString()).map(Holder::value).orElse(null);
|
||||||
|
if (value == null) return false;
|
||||||
|
return register(Registries.DIMENSION_TYPE, new ResourceLocation("iris", name), value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||||
|
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||||
|
if (biomeBase == null) return false;
|
||||||
|
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||||
|
return codec.decode(JsonOps.INSTANCE, GsonHelper.parse(json)).result().map(Pair::getFirst);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Optional<JsonElement> encode(Codec<T> codec, T value) {
|
||||||
|
return codec.encode(value, JsonOps.INSTANCE, new JsonObject()).result();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> boolean register(ResourceKey<Registry<T>> registryKey, ResourceLocation location, T value, boolean replace) {
|
||||||
|
Preconditions.checkArgument(registryKey != null, "The registry cannot be null!");
|
||||||
|
Preconditions.checkArgument(location != null, "The location cannot be null!");
|
||||||
|
Preconditions.checkArgument(value != null, "The value cannot be null!");
|
||||||
|
var registry = registry(registryKey);
|
||||||
|
var key = ResourceKey.create(registryKey, location);
|
||||||
|
try {
|
||||||
|
if (registry.containsKey(key)) {
|
||||||
|
if (!replace) return false;
|
||||||
|
return replace(registryKey, location, value);
|
||||||
|
}
|
||||||
|
Field field = getField(MappedRegistry.class, boolean.class);
|
||||||
|
field.setAccessible(true);
|
||||||
|
boolean frozen = field.getBoolean(registry);
|
||||||
|
field.setBoolean(registry, false);
|
||||||
|
Field valueField = getField(Holder.Reference.class, "T");
|
||||||
|
valueField.setAccessible(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var holder = registry.register(key, value, RegistrationInfo.BUILT_IN);
|
||||||
|
if (frozen) valueField.set(holder, value);
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
field.setBoolean(registry, frozen);
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> boolean replace(ResourceKey<Registry<T>> registryKey, ResourceLocation location, T value) {
|
||||||
|
Preconditions.checkArgument(registryKey != null, "The registryKey cannot be null!");
|
||||||
|
Preconditions.checkArgument(location != null, "The location cannot be null!");
|
||||||
|
Preconditions.checkArgument(value != null, "The value cannot be null!");
|
||||||
|
var registry = registry(registryKey);
|
||||||
|
var key = ResourceKey.create(registryKey, location);
|
||||||
|
try {
|
||||||
|
var holder = registry.getHolder(key).orElse(null);
|
||||||
|
if (holder == null) return false;
|
||||||
|
var oldValue = holder.value();
|
||||||
|
Field valueField = getField(Holder.Reference.class, "T");
|
||||||
|
valueField.setAccessible(true);
|
||||||
|
Field toIdField = getField(MappedRegistry.class, buildType(Reference2IntMap.class, "T"));
|
||||||
|
toIdField.setAccessible(true);
|
||||||
|
Field byValueField = getField(MappedRegistry.class, buildType(Map.class, "T", buildType(Holder.Reference.class, "T")));
|
||||||
|
byValueField.setAccessible(true);
|
||||||
|
var toId = (Reference2IntMap<T>) toIdField.get(registry);
|
||||||
|
var byValue = (Map<T, Holder.Reference<T>>) byValueField.get(registry);
|
||||||
|
|
||||||
|
valueField.set(holder, value);
|
||||||
|
toId.put(value, toId.removeInt(oldValue));
|
||||||
|
byValue.put(value, byValue.remove(oldValue));
|
||||||
|
return true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> MappedRegistry<T> registry(ResourceKey<Registry<T>> registryKey) {
|
||||||
|
var rawRegistry = registry().registry(registryKey).orElse(null);
|
||||||
|
if (!(rawRegistry instanceof MappedRegistry<T> registry))
|
||||||
|
throw new IllegalStateException("The Registry is not a mapped Registry!");
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildType(Class<?> clazz, String... parameterTypes) {
|
||||||
|
if (parameterTypes.length == 0) return clazz.getName();
|
||||||
|
var builder = new StringBuilder(clazz.getName())
|
||||||
|
.append("<");
|
||||||
|
for (int i = 0; i < parameterTypes.length; i++) {
|
||||||
|
builder.append(parameterTypes[i]).append(parameterTypes.length - 1 == i ? ">" : ", ");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field getField(Class<?> clazz, String type) throws NoSuchFieldException {
|
||||||
|
try {
|
||||||
|
for (Field f : clazz.getDeclaredFields()) {
|
||||||
|
if (f.getGenericType().getTypeName().equals(type))
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(type);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
Class<?> superClass = clazz.getSuperclass();
|
||||||
|
if (superClass == null) throw e;
|
||||||
|
return getField(superClass, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
new ByteBuddy()
|
||||||
|
.redefine(ServerLevel.class)
|
||||||
|
.visit(Advice.to(ServerLevelAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(MinecraftServer.class, Executor.class, LevelStorageSource.LevelStorageAccess.class,
|
||||||
|
PrimaryLevelData.class, ResourceKey.class, LevelStem.class, ChunkProgressListener.class, boolean.class, long.class,
|
||||||
|
List.class, boolean.class, RandomSequences.class, World.Environment.class, ChunkGenerator.class, BiomeProvider.class))))
|
||||||
|
.make()
|
||||||
|
.load(ServerLevel.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ServerLevelAdvice {
|
||||||
|
@Advice.OnMethodEnter
|
||||||
|
static void enter(@Advice.Argument(0) MinecraftServer server, @Advice.Argument(2) LevelStorageSource.LevelStorageAccess access, @Advice.Argument(4) ResourceKey<Level> key, @Advice.Argument(value = 5, readOnly = false) LevelStem levelStem) {
|
||||||
|
File iris = new File(access.levelDirectory.path().toFile(), "iris");
|
||||||
|
if (!iris.exists() && !key.location().getPath().startsWith("iris/")) return;
|
||||||
|
ResourceKey<DimensionType> typeKey = ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()));
|
||||||
|
RegistryAccess registryAccess = server.registryAccess();
|
||||||
|
Registry<DimensionType> registry = registryAccess.registry(Registries.DIMENSION_TYPE).orElse(null);
|
||||||
|
if (registry == null) throw new IllegalStateException("Unable to find registry for dimension type " + typeKey);
|
||||||
|
Holder<DimensionType> holder = registry.getHolder(typeKey).orElse(null);
|
||||||
|
if (holder == null) throw new IllegalStateException("Unable to find dimension type " + typeKey);
|
||||||
|
levelStem = new LevelStem(holder, levelStem.generator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ rootProject.name = 'Iris'
|
|||||||
include 'app', 'com.volmit.gui'
|
include 'app', 'com.volmit.gui'
|
||||||
include(':core')
|
include(':core')
|
||||||
include(
|
include(
|
||||||
|
':nms:v1_20_R4',
|
||||||
':nms:v1_20_R3',
|
':nms:v1_20_R3',
|
||||||
':nms:v1_20_R2',
|
':nms:v1_20_R2',
|
||||||
':nms:v1_20_R1',
|
':nms:v1_20_R1',
|
||||||
|
|||||||
Reference in New Issue
Block a user