Compare commits
45 Commits
v0.2.0-bet
...
v0.2.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ec14ff755 | ||
|
|
18e872ad12 | ||
|
|
13c6499854 | ||
|
|
b70443edd5 | ||
|
|
38bab21ddf | ||
|
|
f7d98327e0 | ||
|
|
271a58d2af | ||
|
|
a4f5ef1abd | ||
|
|
d87df61412 | ||
|
|
e917272d3a | ||
|
|
bff8caea54 | ||
|
|
97a865c532 | ||
|
|
f6541b0d91 | ||
|
|
6b4139a5ab | ||
|
|
43164acf5e | ||
|
|
73d73c935a | ||
|
|
7863c556f9 | ||
|
|
c0b02ea709 | ||
|
|
9004f12be6 | ||
|
|
b2144a55aa | ||
|
|
882d733203 | ||
|
|
9b6982bf65 | ||
|
|
5635373cff | ||
|
|
76d2c36481 | ||
|
|
ca791ddc74 | ||
|
|
7f08c11a11 | ||
|
|
93b908350e | ||
|
|
4bd7eb8b72 | ||
|
|
a6cf977c5f | ||
|
|
8ed23bc8f3 | ||
|
|
7034995878 | ||
|
|
ca3d776562 | ||
|
|
1a077389c2 | ||
|
|
49bcc60cf5 | ||
|
|
8b1f31ade8 | ||
|
|
4d88e04e3c | ||
|
|
33889c3850 | ||
|
|
37ac3003cb | ||
|
|
28128d06c1 | ||
|
|
6f9620787b | ||
|
|
cbf6c118dc | ||
|
|
d44fa1f8aa | ||
|
|
3d9ae3f018 | ||
|
|
d24f6c2874 | ||
|
|
f190cdd8cb |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -31,8 +31,6 @@ jobs:
|
|||||||
key: ${{ runner.os }}-project-local-gradle-caches-${{ hashFiles('**/libs.versions.toml', '**/*.gradle*', '**/gradle-wrapper.properties') }}
|
key: ${{ runner.os }}-project-local-gradle-caches-${{ hashFiles('**/libs.versions.toml', '**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-project-local-gradle-caches-
|
${{ runner.os }}-project-local-gradle-caches-
|
||||||
- name: "setup concurrentutil"
|
|
||||||
run: ./installConcurrentUtil.sh
|
|
||||||
- name: "execute gradle build"
|
- name: "execute gradle build"
|
||||||
run: ./gradlew build
|
run: ./gradlew build
|
||||||
- name: Determine Snapshot Status
|
- name: Determine Snapshot Status
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -116,3 +116,6 @@ run/
|
|||||||
|
|
||||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
|
|
||||||
|
ConcurrentUtil/
|
||||||
|
YamlConfig/
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "ConcurrentUtil"]
|
|
||||||
path = ConcurrentUtil
|
|
||||||
url = https://github.com/Spottedleaf/ConcurrentUtil.git
|
|
||||||
|
|||||||
Submodule ConcurrentUtil deleted from 08d3ca3241
121
build.gradle
121
build.gradle
@@ -1,40 +1,53 @@
|
|||||||
import me.modmuss50.mpp.ReleaseType
|
import me.modmuss50.mpp.ReleaseType
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("xyz.jpenilla.quiet-architectury-loom")
|
id("java-library")
|
||||||
id("me.modmuss50.mod-publish-plugin") version "0.7.2" apply false
|
id("net.neoforged.moddev")
|
||||||
|
id("me.modmuss50.mod-publish-plugin") version "0.8.4" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
extensions.create("runConfigCommon", RunConfigCommon.class)
|
||||||
* Gets the version name from the latest Git tag
|
|
||||||
*/
|
def getGitCommit = providers.exec {
|
||||||
// https://stackoverflow.com/questions/28498688/gradle-script-to-autoversion-and-include-the-commit-hash-in-android
|
commandLine 'git', 'rev-parse', '--short', 'HEAD'
|
||||||
def getGitCommit = { ->
|
}.standardOutput.getAsText().map { it.trim() }
|
||||||
def stdout = new ByteArrayOutputStream()
|
|
||||||
exec {
|
def aw2at = Aw2AtTask.configureDefault(
|
||||||
commandLine 'git', 'rev-parse', '--short', 'HEAD'
|
getProject(),
|
||||||
standardOutput = stdout
|
layout.projectDirectory.file("src/main/resources/moonrise.accesswidener").getAsFile(),
|
||||||
}
|
sourceSets.main
|
||||||
return stdout.toString().trim()
|
)
|
||||||
|
|
||||||
|
neoForge {
|
||||||
|
neoFormVersion = neoform_version
|
||||||
|
validateAccessTransformers = true
|
||||||
|
accessTransformers.files.setFrom(aw2at.flatMap { t -> t.getOutputFile() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runConfigCommon {
|
||||||
|
systemProperties.put "mixin.debug", "true"
|
||||||
|
systemProperties.put "Moonrise.MaxViewDistance", "128"
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
compileOnly "net.fabricmc:sponge-mixin:0.15.4+mixin.0.8.7"
|
||||||
|
compileOnly "io.github.llamalad7:mixinextras-common:0.4.1"
|
||||||
|
// work around minecraft (MDG) forcing ASM 9.3 which is incompatible with the above deps...
|
||||||
|
components.withModule("net.neoforged:minecraft-dependencies", RemoveAsmConstraint.class)
|
||||||
|
|
||||||
api("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}")
|
api("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}") { setTransitive(false) }
|
||||||
|
api("ca.spottedleaf:yamlconfig:${rootProject.yamlconfig_version}") { setTransitive(false) }
|
||||||
api("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
api("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
||||||
|
|
||||||
modImplementation "me.shedaniel.cloth:cloth-config:${rootProject.cloth_version}"
|
// todo: does cloth publish a platform-agnostic jar in mojang mappings?
|
||||||
|
compileOnly "me.shedaniel.cloth:cloth-config-neoforge:${rootProject.cloth_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
File awFile = file("src/main/resources/moonrise.accesswidener")
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = rootProject.maven_group
|
group = rootProject.maven_group
|
||||||
version = rootProject.mod_version + "+" + getGitCommit()
|
version = rootProject.mod_version + "+" + getGitCommit.get()
|
||||||
|
|
||||||
plugins.apply("xyz.jpenilla.quiet-architectury-loom")
|
plugins.apply("java-library")
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
@@ -44,10 +57,20 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter:${rootProject.junit_version}"
|
||||||
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal {
|
maven {
|
||||||
|
url "https://repo.papermc.io/repository/maven-public/"
|
||||||
mavenContent {
|
mavenContent {
|
||||||
includeModule("ca.spottedleaf", "concurrentutil")
|
includeGroup("ca.spottedleaf")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
@@ -60,11 +83,6 @@ allprojects {
|
|||||||
maven { url "https://maven.terraformersmc.com/releases/" }
|
maven { url "https://maven.terraformersmc.com/releases/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
|
||||||
mappings loom.officialMojangMappings()
|
|
||||||
}
|
|
||||||
|
|
||||||
// make build reproducible
|
// make build reproducible
|
||||||
tasks.withType(AbstractArchiveTask).configureEach {
|
tasks.withType(AbstractArchiveTask).configureEach {
|
||||||
preserveFileTimestamps = false
|
preserveFileTimestamps = false
|
||||||
@@ -80,32 +98,22 @@ allprojects {
|
|||||||
rename { "${it}_${rootProject.base.archivesName.get()}"}
|
rename { "${it}_${rootProject.base.archivesName.get()}"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
|
||||||
accessWidenerPath = awFile
|
|
||||||
mixin {
|
|
||||||
useLegacyMixinAp = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
loom.mods {
|
|
||||||
main {
|
|
||||||
sourceSet("main")
|
|
||||||
sourceSet("main", project.rootProject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loom.runs.all {
|
|
||||||
ideConfigGenerated true
|
|
||||||
property "mixin.debug", "true"
|
|
||||||
property "Moonrise.MaxViewDistance", "128"
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins.apply("me.modmuss50.mod-publish-plugin")
|
plugins.apply("me.modmuss50.mod-publish-plugin")
|
||||||
|
plugins.apply 'java-library'
|
||||||
|
plugins.apply 'com.gradleup.shadow'
|
||||||
|
|
||||||
|
configurations.create("libs")
|
||||||
|
configurations.shadow {
|
||||||
|
extendsFrom(configurations.libs)
|
||||||
|
}
|
||||||
|
configurations.implementation {
|
||||||
|
extendsFrom(configurations.libs)
|
||||||
|
}
|
||||||
|
|
||||||
publishMods {
|
publishMods {
|
||||||
file = remapJar.archiveFile
|
|
||||||
if (project.version.contains("-beta.")) {
|
if (project.version.contains("-beta.")) {
|
||||||
type = ReleaseType.BETA
|
type = ReleaseType.BETA
|
||||||
} else {
|
} else {
|
||||||
@@ -129,20 +137,7 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup a run with lithium for compatibility testing
|
// Setup a run with lithium for compatibility testing
|
||||||
sourceSets.create("lithium")
|
|
||||||
configurations.create("lithium")
|
configurations.create("lithium")
|
||||||
loom {
|
|
||||||
createRemapConfigurations(sourceSets.lithium)
|
|
||||||
runs {
|
|
||||||
register("lithiumClient") {
|
|
||||||
client()
|
|
||||||
property "mixin.debug", "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks.named("runLithiumClient", net.fabricmc.loom.task.RunGameTask.class) {
|
|
||||||
getClasspath().from(configurations.modRuntimeClasspathLithiumMapped)
|
|
||||||
}
|
|
||||||
dependencies {
|
dependencies {
|
||||||
String coordinates = "maven.modrinth:lithium:"
|
String coordinates = "maven.modrinth:lithium:"
|
||||||
if (getProject().name == "Moonrise-NeoForge") {
|
if (getProject().name == "Moonrise-NeoForge") {
|
||||||
@@ -150,10 +145,6 @@ subprojects {
|
|||||||
} else {
|
} else {
|
||||||
coordinates += rootProject.fabric_lithium_version
|
coordinates += rootProject.fabric_lithium_version
|
||||||
}
|
}
|
||||||
modLithiumRuntimeOnly coordinates
|
lithium coordinates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loom.runs.all {
|
|
||||||
ideConfigGenerated false
|
|
||||||
}
|
|
||||||
|
|||||||
11
buildSrc/build.gradle.kts
Normal file
11
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://maven.fabricmc.net/")
|
||||||
|
maven("https://maven.architectury.dev/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("net.fabricmc:access-widener:2.1.0")
|
||||||
|
implementation("dev.architectury:at:1.0.1")
|
||||||
|
}
|
||||||
130
buildSrc/src/main/java/Aw2AtTask.java
Normal file
130
buildSrc/src/main/java/Aw2AtTask.java
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import dev.architectury.at.AccessChange;
|
||||||
|
import dev.architectury.at.AccessTransform;
|
||||||
|
import dev.architectury.at.AccessTransformSet;
|
||||||
|
import dev.architectury.at.ModifierChange;
|
||||||
|
import dev.architectury.at.io.AccessTransformFormats;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.fabricmc.accesswidener.AccessWidenerReader;
|
||||||
|
import net.fabricmc.accesswidener.AccessWidenerVisitor;
|
||||||
|
import org.cadixdev.bombe.type.signature.MethodSignature;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.file.ProjectLayout;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.tasks.CacheableTask;
|
||||||
|
import org.gradle.api.tasks.InputFile;
|
||||||
|
import org.gradle.api.tasks.OutputFile;
|
||||||
|
import org.gradle.api.tasks.PathSensitive;
|
||||||
|
import org.gradle.api.tasks.PathSensitivity;
|
||||||
|
import org.gradle.api.tasks.SourceSet;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.gradle.api.tasks.TaskProvider;
|
||||||
|
|
||||||
|
@CacheableTask
|
||||||
|
public abstract class Aw2AtTask extends DefaultTask {
|
||||||
|
|
||||||
|
@InputFile
|
||||||
|
@PathSensitive(PathSensitivity.NONE)
|
||||||
|
public abstract RegularFileProperty getInputFile();
|
||||||
|
|
||||||
|
@OutputFile
|
||||||
|
public abstract RegularFileProperty getOutputFile();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public abstract ProjectLayout getLayout();
|
||||||
|
|
||||||
|
public static TaskProvider<Aw2AtTask> configureDefault(
|
||||||
|
final Project project,
|
||||||
|
final File awFile,
|
||||||
|
final SourceSet sourceSet
|
||||||
|
) {
|
||||||
|
final TaskProvider<Aw2AtTask> aw2at = project.getTasks().register("aw2at", Aw2AtTask.class, task -> {
|
||||||
|
task.getOutputFile().set(project.getLayout().getBuildDirectory().file("aw2at/files/accesstransformer.cfg"));
|
||||||
|
task.getInputFile().set(awFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
final TaskProvider<CopyTask> copyTask = project.getTasks().register("copyAt", CopyTask.class, copy -> {
|
||||||
|
copy.getInputFile().set(aw2at.flatMap(Aw2AtTask::getOutputFile));
|
||||||
|
copy.getOutputDirectory().set(project.getLayout().getBuildDirectory().dir("aw2at/dir"));
|
||||||
|
copy.getDestination().set("META-INF/accesstransformer.cfg");
|
||||||
|
});
|
||||||
|
|
||||||
|
sourceSet.resources(resources -> {
|
||||||
|
resources.srcDir(copyTask.flatMap(CopyTask::getOutputDirectory));
|
||||||
|
});
|
||||||
|
|
||||||
|
return aw2at;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void run() {
|
||||||
|
try (final BufferedReader reader = Files.newBufferedReader(this.getInputFile().get().getAsFile().toPath())) {
|
||||||
|
final AccessTransformSet accessTransformSet = toAccessTransformSet(reader);
|
||||||
|
Files.deleteIfExists(this.getOutputFile().get().getAsFile().toPath());
|
||||||
|
Files.createDirectories(this.getOutputFile().get().getAsFile().toPath().getParent());
|
||||||
|
AccessTransformFormats.FML.write(this.getOutputFile().get().getAsFile().toPath(), accessTransformSet);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below methods are heavily based on architectury-loom Aw2At class (MIT licensed)
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 FabricMC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static AccessTransformSet toAccessTransformSet(final BufferedReader reader) throws IOException {
|
||||||
|
// TODO: Remove copied classes once https://github.com/architectury/at/pull/1 is released
|
||||||
|
AccessTransformSet atSet = new at.AccessTransformSetImpl();
|
||||||
|
|
||||||
|
new AccessWidenerReader(new AccessWidenerVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitClass(final String name, final AccessWidenerReader.AccessType access, final boolean transitive) {
|
||||||
|
atSet.getOrCreateClass(name).merge(toAt(access));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitMethod(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
|
||||||
|
atSet.getOrCreateClass(owner).mergeMethod(MethodSignature.of(name, descriptor), toAt(access));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitField(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
|
||||||
|
atSet.getOrCreateClass(owner).mergeField(name, toAt(access));
|
||||||
|
}
|
||||||
|
}).read(reader);
|
||||||
|
|
||||||
|
return atSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccessTransform toAt(final AccessWidenerReader.AccessType access) {
|
||||||
|
return switch (access) {
|
||||||
|
case ACCESSIBLE -> AccessTransform.of(AccessChange.PUBLIC);
|
||||||
|
case EXTENDABLE, MUTABLE -> AccessTransform.of(AccessChange.PUBLIC, ModifierChange.REMOVE);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
44
buildSrc/src/main/java/CopyTask.java
Normal file
44
buildSrc/src/main/java/CopyTask.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.file.DirectoryProperty;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.provider.Property;
|
||||||
|
import org.gradle.api.tasks.Input;
|
||||||
|
import org.gradle.api.tasks.InputFile;
|
||||||
|
import org.gradle.api.tasks.OutputDirectory;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
|
||||||
|
public abstract class CopyTask extends DefaultTask {
|
||||||
|
|
||||||
|
@InputFile
|
||||||
|
public abstract RegularFileProperty getInputFile();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public abstract Property<String> getDestination();
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
public abstract DirectoryProperty getOutputDirectory();
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void run() {
|
||||||
|
final Path outputDirPath = this.getOutputDirectory().get().getAsFile().toPath();
|
||||||
|
try {
|
||||||
|
try (final Stream<Path> walk = Files.walk(outputDirPath)) {
|
||||||
|
for (final Path path : walk.sorted(Comparator.reverseOrder()).toList()) {
|
||||||
|
Files.delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Path destFile = outputDirPath.resolve(this.getDestination().get());
|
||||||
|
Files.createDirectories(destFile.getParent());
|
||||||
|
|
||||||
|
Files.copy(this.getInputFile().get().getAsFile().toPath(), destFile);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
buildSrc/src/main/java/RemoveAsmConstraint.java
Normal file
24
buildSrc/src/main/java/RemoveAsmConstraint.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import java.util.Objects;
|
||||||
|
import org.gradle.api.artifacts.CacheableRule;
|
||||||
|
import org.gradle.api.artifacts.ComponentMetadataContext;
|
||||||
|
import org.gradle.api.artifacts.ComponentMetadataRule;
|
||||||
|
|
||||||
|
@CacheableRule
|
||||||
|
public abstract class RemoveAsmConstraint implements ComponentMetadataRule {
|
||||||
|
@Override
|
||||||
|
public void execute(final ComponentMetadataContext ctx) {
|
||||||
|
ctx.getDetails().allVariants(variants -> {
|
||||||
|
variants.withDependencies(deps -> {
|
||||||
|
deps.forEach(dep -> {
|
||||||
|
if (Objects.equals(dep.getGroup(), "org.ow2.asm")) {
|
||||||
|
if (dep.getVersionConstraint().getStrictVersion() != null) {
|
||||||
|
dep.version(v -> {
|
||||||
|
v.require(v.getStrictVersion());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
5
buildSrc/src/main/java/RunConfigCommon.java
Normal file
5
buildSrc/src/main/java/RunConfigCommon.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import org.gradle.api.provider.MapProperty;
|
||||||
|
|
||||||
|
public abstract class RunConfigCommon {
|
||||||
|
public abstract MapProperty<String, String> getSystemProperties();
|
||||||
|
}
|
||||||
97
buildSrc/src/main/java/at/AccessTransformSetImpl.java
Normal file
97
buildSrc/src/main/java/at/AccessTransformSetImpl.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Architectury
|
||||||
|
* Copyright (c) 2018 Minecrell (https://github.com/Minecrell)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package at;
|
||||||
|
|
||||||
|
import dev.architectury.at.AccessTransformSet;
|
||||||
|
import net.fabricmc.mappingio.tree.MappingTreeView;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class AccessTransformSetImpl implements AccessTransformSet {
|
||||||
|
|
||||||
|
private final Map<String, Class> classes = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Class> getClasses() {
|
||||||
|
return Collections.unmodifiableMap(this.classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Class> getClass(String name) {
|
||||||
|
Objects.requireNonNull(name, "name");
|
||||||
|
return Optional.ofNullable(this.classes.get(name.replace('.', '/')));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getOrCreateClass(String name) {
|
||||||
|
Objects.requireNonNull(name, "name");
|
||||||
|
return this.classes.computeIfAbsent(name.replace('.', '/'), n -> new ClassAccessTransformSetImpl(this, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Class> removeClass(String name) {
|
||||||
|
Objects.requireNonNull(name, "name");
|
||||||
|
return Optional.ofNullable(this.classes.remove(name.replace('.', '/')));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransformSet remap(MappingTreeView mappings, String from, String to) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void merge(AccessTransformSet other) {
|
||||||
|
other.getClasses().forEach((name, classSet) -> getOrCreateClass(name).merge(classSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof AccessTransformSetImpl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessTransformSetImpl that = (AccessTransformSetImpl) o;
|
||||||
|
return this.classes.equals(that.classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.classes.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AccessTransformSet{" + classes + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
256
buildSrc/src/main/java/at/ClassAccessTransformSetImpl.java
Normal file
256
buildSrc/src/main/java/at/ClassAccessTransformSetImpl.java
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Architectury
|
||||||
|
* Copyright (c) 2018 Minecrell (https://github.com/Minecrell)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package at;
|
||||||
|
|
||||||
|
import dev.architectury.at.AccessTransform;
|
||||||
|
import dev.architectury.at.AccessTransformSet;
|
||||||
|
import org.cadixdev.bombe.analysis.InheritanceProvider;
|
||||||
|
import org.cadixdev.bombe.type.signature.MethodSignature;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
class ClassAccessTransformSetImpl implements AccessTransformSet.Class {
|
||||||
|
|
||||||
|
private final AccessTransformSet parent;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private AccessTransform classTransform = AccessTransform.EMPTY;
|
||||||
|
private AccessTransform allFields = AccessTransform.EMPTY;
|
||||||
|
private AccessTransform allMethods = AccessTransform.EMPTY;
|
||||||
|
|
||||||
|
private final Map<String, AccessTransform> fields = new LinkedHashMap<>();
|
||||||
|
private final Map<MethodSignature, AccessTransform> methods = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
private boolean complete;
|
||||||
|
|
||||||
|
ClassAccessTransformSetImpl(AccessTransformSet parent, String name) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransformSet getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform get() {
|
||||||
|
return this.classTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform merge(AccessTransform transform) {
|
||||||
|
return this.classTransform = this.classTransform.merge(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform replace(AccessTransform transform) {
|
||||||
|
return this.classTransform = Objects.requireNonNull(transform, "transform");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform allFields() {
|
||||||
|
return this.allFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform mergeAllFields(AccessTransform transform) {
|
||||||
|
return this.allFields = this.allFields.merge(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform replaceAllFields(AccessTransform transform) {
|
||||||
|
return this.allFields = Objects.requireNonNull(transform, "transform");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform allMethods() {
|
||||||
|
return this.allMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform mergeAllMethods(AccessTransform transform) {
|
||||||
|
return this.allMethods = this.allMethods.merge(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform replaceAllMethods(AccessTransform transform) {
|
||||||
|
return this.allMethods = Objects.requireNonNull(transform, "transform");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, AccessTransform> getFields() {
|
||||||
|
return Collections.unmodifiableMap(this.fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform getField(String name) {
|
||||||
|
return this.fields.getOrDefault(Objects.requireNonNull(name, "name"), this.allFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform mergeField(String name, AccessTransform transform) {
|
||||||
|
Objects.requireNonNull(name, "name");
|
||||||
|
Objects.requireNonNull(transform, "transform");
|
||||||
|
|
||||||
|
if (transform.isEmpty()) {
|
||||||
|
return this.fields.getOrDefault(name, AccessTransform.EMPTY);
|
||||||
|
}
|
||||||
|
return this.fields.merge(name, transform, AccessTransform::merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform replaceField(String name, AccessTransform transform) {
|
||||||
|
Objects.requireNonNull(name, "name");
|
||||||
|
Objects.requireNonNull(transform, "transform");
|
||||||
|
|
||||||
|
if (transform.isEmpty()) {
|
||||||
|
return this.fields.remove(name);
|
||||||
|
}
|
||||||
|
return this.fields.put(name, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<MethodSignature, AccessTransform> getMethods() {
|
||||||
|
return Collections.unmodifiableMap(this.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform getMethod(MethodSignature signature) {
|
||||||
|
return this.methods.getOrDefault(Objects.requireNonNull(signature, "signature"), this.allMethods);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform mergeMethod(MethodSignature signature, AccessTransform transform) {
|
||||||
|
Objects.requireNonNull(signature, "signature");
|
||||||
|
Objects.requireNonNull(transform, "transform");
|
||||||
|
|
||||||
|
if (transform.isEmpty()) {
|
||||||
|
return this.methods.getOrDefault(signature, AccessTransform.EMPTY);
|
||||||
|
}
|
||||||
|
return this.methods.merge(signature, transform, AccessTransform::merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessTransform replaceMethod(MethodSignature signature, AccessTransform transform) {
|
||||||
|
Objects.requireNonNull(signature, "signature");
|
||||||
|
Objects.requireNonNull(transform, "transform");
|
||||||
|
|
||||||
|
if (transform.isEmpty()) {
|
||||||
|
return this.methods.remove(signature);
|
||||||
|
}
|
||||||
|
return this.methods.put(signature, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void merge(AccessTransformSet.Class other) {
|
||||||
|
Objects.requireNonNull(other, "other");
|
||||||
|
|
||||||
|
merge(other.get());
|
||||||
|
mergeAllFields(other.allFields());
|
||||||
|
mergeAllMethods(other.allMethods());
|
||||||
|
|
||||||
|
other.getFields().forEach(this::mergeField);
|
||||||
|
other.getMethods().forEach(this::mergeMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isComplete() {
|
||||||
|
return this.complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete(InheritanceProvider provider, InheritanceProvider.ClassInfo info) {
|
||||||
|
if (this.complete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InheritanceProvider.ClassInfo parent : info.provideParents(provider)) {
|
||||||
|
AccessTransformSet.Class parentAts = getParent().getOrCreateClass(parent.getName());
|
||||||
|
parentAts.complete(provider, parent);
|
||||||
|
|
||||||
|
parentAts.getMethods().forEach((signature, transform) -> {
|
||||||
|
if (info.overrides(signature, parent)) {
|
||||||
|
mergeMethod(signature, transform);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof ClassAccessTransformSetImpl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassAccessTransformSetImpl that = (ClassAccessTransformSetImpl) o;
|
||||||
|
return this.classTransform.equals(that.classTransform) &&
|
||||||
|
this.allFields.equals(that.allFields) &&
|
||||||
|
this.allMethods.equals(that.allMethods) &&
|
||||||
|
this.fields.equals(that.fields) &&
|
||||||
|
this.methods.equals(that.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.classTransform, this.allFields, this.allMethods, this.fields, this.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringJoiner joiner = new StringJoiner(", ", "AccessTransformSet.Class{", "}");
|
||||||
|
if (!this.classTransform.isEmpty()) {
|
||||||
|
joiner.add(this.classTransform.toString());
|
||||||
|
}
|
||||||
|
if (!this.allFields.isEmpty()) {
|
||||||
|
joiner.add("allFields=" + this.allFields);
|
||||||
|
}
|
||||||
|
if (!this.allMethods.isEmpty()) {
|
||||||
|
joiner.add("allMethods=" + this.allMethods);
|
||||||
|
}
|
||||||
|
if (!this.fields.isEmpty()) {
|
||||||
|
joiner.add("fields=" + this.fields);
|
||||||
|
}
|
||||||
|
if (!this.methods.isEmpty()) {
|
||||||
|
joiner.add("method=" + this.methods);
|
||||||
|
}
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,52 +1,60 @@
|
|||||||
plugins {
|
import java.util.stream.Collectors
|
||||||
id("xyz.jpenilla.quiet-architectury-loom")
|
import net.fabricmc.loom.util.gradle.SourceSetHelper
|
||||||
id 'maven-publish'
|
|
||||||
id 'com.gradleup.shadow'
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.create("libs")
|
plugins {
|
||||||
configurations.shadow {
|
id("quiet-fabric-loom")
|
||||||
extendsFrom(configurations.libs)
|
id 'maven-publish'
|
||||||
}
|
|
||||||
configurations.implementation {
|
|
||||||
extendsFrom(configurations.libs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
add('shadow', project([path: ":", configuration: "namedElements"]))
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
runtimeOnly(project(":").sourceSets.main.output)
|
mappings loom.officialMojangMappings()
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}"
|
||||||
|
|
||||||
libs("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}")
|
runtimeOnly(project(":").sourceSets.main.output)
|
||||||
|
shadow(project(":"))
|
||||||
|
compileOnly(project(":"))
|
||||||
|
|
||||||
|
libs("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}") { setTransitive(false) }
|
||||||
|
libs("ca.spottedleaf:yamlconfig:${rootProject.yamlconfig_version}") { setTransitive(false) }
|
||||||
libs("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
libs("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
||||||
|
|
||||||
modImplementation "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_version}"
|
modImplementation "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_version}"
|
||||||
include "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_version}"
|
include "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_version}"
|
||||||
modImplementation "com.terraformersmc:modmenu:${rootProject.modmenu_version}"
|
modImplementation "com.terraformersmc:modmenu:${rootProject.modmenu_version}"
|
||||||
|
|
||||||
|
modImplementation platform(fabricApiLibs.bom)
|
||||||
modImplementation fabricApiLibs.command.api.v2
|
modImplementation fabricApiLibs.command.api.v2
|
||||||
modImplementation fabricApiLibs.lifecycle.events.v1
|
modImplementation fabricApiLibs.lifecycle.events.v1
|
||||||
include fabricApiLibs.command.api.v2
|
include fabricApiLibs.command.api.v2
|
||||||
include fabricApiLibs.base
|
include fabricApiLibs.base
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
tasks.processResources {
|
||||||
inputs.property "version", project.version
|
def properties = [
|
||||||
|
"version": project.version,
|
||||||
|
"minecraft_version": minecraft_version,
|
||||||
|
"loader_version": loader_version,
|
||||||
|
"mod_version": mod_version
|
||||||
|
]
|
||||||
|
inputs.properties(properties)
|
||||||
filesMatching("fabric.mod.json") {
|
filesMatching("fabric.mod.json") {
|
||||||
expand "version": project.version, "minecraft_version": minecraft_version, "loader_version": loader_version, "mod_version": mod_version
|
expand properties
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
tasks.shadowJar {
|
||||||
archiveClassifier = "dev-all"
|
archiveClassifier = "dev-all"
|
||||||
destinationDirectory = layout.buildDirectory.dir("libs")
|
destinationDirectory = layout.buildDirectory.dir("libs")
|
||||||
configurations = [project.configurations.shadow]
|
configurations = [project.configurations.shadow]
|
||||||
relocate 'ca.spottedleaf.concurrentutil', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.concurrentutil'
|
relocate 'ca.spottedleaf.concurrentutil', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.concurrentutil'
|
||||||
|
relocate 'ca.spottedleaf.yamlconfig', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.yamlconfig'
|
||||||
relocate 'org.yaml.snakeyaml', 'ca.spottedleaf.moonrise.libs.org.yaml.snakeyaml'
|
relocate 'org.yaml.snakeyaml', 'ca.spottedleaf.moonrise.libs.org.yaml.snakeyaml'
|
||||||
}
|
}
|
||||||
|
|
||||||
publishMods {
|
publishMods {
|
||||||
|
file = remapJar.archiveFile
|
||||||
modLoaders = ["fabric"]
|
modLoaders = ["fabric"]
|
||||||
|
|
||||||
modrinth {
|
modrinth {
|
||||||
@@ -64,3 +72,52 @@ publishMods {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loom {
|
||||||
|
accessWidenerPath.set(getRootProject().file("src/main/resources/moonrise.accesswidener"))
|
||||||
|
mixin {
|
||||||
|
useLegacyMixinAp = false
|
||||||
|
}
|
||||||
|
runs.configureEach {
|
||||||
|
ideConfigGenerated true
|
||||||
|
}
|
||||||
|
mods {
|
||||||
|
main {
|
||||||
|
sourceSet("main")
|
||||||
|
sourceSet("main", project.rootProject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
def classPathGroups = SourceSetHelper.getClasspath(loom.mods.main, getProject()).stream()
|
||||||
|
.map(File.&getAbsolutePath)
|
||||||
|
.collect(Collectors.joining(File.pathSeparator))
|
||||||
|
|
||||||
|
systemProperty("fabric.classPathGroups", classPathGroups)
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
loom.runs.configureEach { cfg ->
|
||||||
|
runConfigCommon.systemProperties.get().each {
|
||||||
|
cfg.property it.key, it.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup a run with lithium for compatibility testing
|
||||||
|
sourceSets.create("lithium")
|
||||||
|
loom {
|
||||||
|
createRemapConfigurations(sourceSets.lithium)
|
||||||
|
runs {
|
||||||
|
register("lithiumClient") {
|
||||||
|
client()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configurations.modLithiumRuntimeOnly {
|
||||||
|
extendsFrom configurations.lithium
|
||||||
|
}
|
||||||
|
tasks.named("runLithiumClient", net.fabricmc.loom.task.RunGameTask.class) {
|
||||||
|
getClasspath().from(configurations.modRuntimeClasspathLithiumMapped)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ca.spottedleaf.moonrise.fabric;
|
package ca.spottedleaf.moonrise.fabric;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.BaseChunkSystemHooks;
|
||||||
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.util.ConfigHolder;
|
import ca.spottedleaf.moonrise.common.util.ConfigHolder;
|
||||||
import com.mojang.datafixers.DSL;
|
import com.mojang.datafixers.DSL;
|
||||||
@@ -15,6 +16,7 @@ import net.minecraft.server.level.GenerationChunkHolder;
|
|||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -27,10 +29,11 @@ import net.minecraft.world.level.chunk.status.ChunkStatusTasks;
|
|||||||
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
|
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
|
||||||
import net.minecraft.world.level.entity.EntityTypeTest;
|
import net.minecraft.world.level.entity.EntityTypeTest;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public final class FabricHooks implements PlatformHooks {
|
public final class FabricHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||||
|
|
||||||
private static final boolean HAS_FABRIC_LIFECYCLE_EVENTS = FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1");
|
private static final boolean HAS_FABRIC_LIFECYCLE_EVENTS = FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1");
|
||||||
|
|
||||||
@@ -111,13 +114,43 @@ public final class FabricHooks implements PlatformHooks {
|
|||||||
@Override
|
@Override
|
||||||
public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
|
public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
|
||||||
final List<Entity> into) {
|
final List<Entity> into) {
|
||||||
|
final Collection<EnderDragonPart> parts = world.dragonParts();
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final EnderDragonPart part : parts) {
|
||||||
|
if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
|
||||||
|
into.add(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox,
|
public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox,
|
||||||
final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
|
final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
|
||||||
|
if (into.size() >= maxCount) {
|
||||||
|
// fix neoforge issue: do not add if list is already full
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Collection<EnderDragonPart> parts = world.dragonParts();
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final EnderDragonPart part : parts) {
|
||||||
|
if (!part.getBoundingBox().intersects(boundingBox)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final T casted = (T)entityTypeTest.tryCast(part);
|
||||||
|
if (casted != null && (predicate == null || predicate.test(casted))) {
|
||||||
|
into.add(casted);
|
||||||
|
if (into.size() >= maxCount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
"accessWidener": "moonrise.accesswidener",
|
"accessWidener": "moonrise.accesswidener",
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=${loader_version}",
|
"fabricloader": ">=${loader_version}",
|
||||||
"minecraft": ">1.21.1 <1.21.4",
|
"minecraft": ">1.21.3 <1.21.5",
|
||||||
"fabric-command-api-v2": "*"
|
"fabric-command-api-v2": "*"
|
||||||
},
|
},
|
||||||
"custom": {
|
"custom": {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package ca.spottedleaf.moonrise.fabric;
|
||||||
|
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.server.Bootstrap;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||||
|
|
||||||
|
class MixinAuditTest {
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() {
|
||||||
|
SharedConstants.tryDetectVersion();
|
||||||
|
Bootstrap.bootStrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditMixins() {
|
||||||
|
MixinEnvironment.getCurrentEnvironment().audit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,25 @@
|
|||||||
# Done to increase the memory available to gradle.
|
# Done to increase the memory available to gradle.
|
||||||
org.gradle.jvmargs=-Xmx2G
|
org.gradle.jvmargs=-Xmx2G
|
||||||
org.gradle.daemon=false
|
org.gradle.parallel=true
|
||||||
|
org.gradle.caching=true
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://modmuss50.me/fabric.html
|
# check these on https://modmuss50.me/fabric.html
|
||||||
minecraft_version=1.21.3
|
minecraft_version=1.21.4
|
||||||
loader_version=0.16.7
|
loader_version=0.16.9
|
||||||
supported_minecraft_versions=1.21.3
|
supported_minecraft_versions=1.21.4
|
||||||
neoforge_version=21.3.31-beta
|
neoforge_version=21.4.33-beta
|
||||||
fabric_api_version=0.107.0+1.21.3
|
neoform_version=1.21.4-20241203.161809
|
||||||
snakeyaml_version=2.2
|
fabric_api_version=0.110.5+1.21.4
|
||||||
concurrentutil_version=0.0.2-SNAPSHOT
|
snakeyaml_version=2.3
|
||||||
cloth_version=16.0.141
|
concurrentutil_version=0.0.2
|
||||||
modmenu_version=12.0.0-beta.1
|
yamlconfig_version=1.0.2
|
||||||
|
cloth_version=17.0.144
|
||||||
|
modmenu_version=13.0.0-beta.1
|
||||||
|
junit_version=5.11.3
|
||||||
# version ids from modrinth
|
# version ids from modrinth
|
||||||
fabric_lithium_version=QhCwdt4l
|
fabric_lithium_version=t1FlWYl9
|
||||||
neo_lithium_version=wDD955sb
|
neo_lithium_version=iDqQi66g
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=0.2.0-beta.4
|
mod_version=0.2.0-beta.7
|
||||||
maven_group=ca.spottedleaf.moonrise
|
maven_group=ca.spottedleaf.moonrise
|
||||||
archives_base_name=moonrise
|
archives_base_name=moonrise
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
3
gradlew
vendored
3
gradlew
vendored
@@ -86,8 +86,7 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
' "$PWD" ) || exit
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -eou pipefail
|
|
||||||
|
|
||||||
git submodule update --init --recursive
|
|
||||||
cd ConcurrentUtil
|
|
||||||
mvn install
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import net.fabricmc.loom.util.aw2at.Aw2At
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
import net.neoforged.moddevgradle.internal.RunGameTask
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("xyz.jpenilla.quiet-architectury-loom")
|
id("net.neoforged.moddev")
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id 'com.gradleup.shadow'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -13,41 +14,88 @@ repositories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.implementation {
|
def aw2at = Aw2AtTask.configureDefault(
|
||||||
extendsFrom(configurations.shadow)
|
getProject(),
|
||||||
}
|
rootProject.layout.projectDirectory.file("src/main/resources/moonrise.accesswidener").getAsFile(),
|
||||||
|
sourceSets.main
|
||||||
|
)
|
||||||
|
|
||||||
dependencies {
|
neoForge {
|
||||||
add('shadow', project([path: ":", configuration: "namedElements"]))
|
version = rootProject.neoforge_version
|
||||||
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
|
validateAccessTransformers = true
|
||||||
|
accessTransformers.files.setFrom(aw2at.flatMap { t -> t.getOutputFile() })
|
||||||
shadow("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}")
|
mods {
|
||||||
shadow("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
moonrise {
|
||||||
forgeExtra("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
sourceSet sourceSets.main
|
||||||
|
sourceSet rootProject.sourceSets.main
|
||||||
modImplementation "me.shedaniel.cloth:cloth-config-neoforge:${rootProject.cloth_version}"
|
}
|
||||||
include "me.shedaniel.cloth:cloth-config-neoforge:${rootProject.cloth_version}"
|
}
|
||||||
}
|
runs {
|
||||||
|
client {
|
||||||
processResources {
|
client()
|
||||||
inputs.property "version", project.version
|
}
|
||||||
|
server {
|
||||||
filesMatching("META-INF/neoforge.mods.toml") {
|
server()
|
||||||
expand "version": project.version, "minecraft_version": minecraft_version, "loader_version": loader_version, "mod_version": mod_version
|
}
|
||||||
|
}
|
||||||
|
unitTest {
|
||||||
|
enable()
|
||||||
|
testedMod = mods.moonrise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
dependencies {
|
||||||
|
runtimeOnly(project(":").sourceSets.main.output)
|
||||||
|
shadow(project(":"))
|
||||||
|
compileOnly(project(":"))
|
||||||
|
|
||||||
|
libs("ca.spottedleaf:concurrentutil:${rootProject.concurrentutil_version}") { setTransitive(false) }
|
||||||
|
libs("ca.spottedleaf:yamlconfig:${rootProject.yamlconfig_version}") { setTransitive(false) }
|
||||||
|
additionalRuntimeClasspath libs("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
|
||||||
|
|
||||||
|
implementation "me.shedaniel.cloth:cloth-config-neoforge:${rootProject.cloth_version}"
|
||||||
|
jarJar "me.shedaniel.cloth:cloth-config-neoforge:${rootProject.cloth_version}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.processResources {
|
||||||
|
def properties = [
|
||||||
|
"version": project.version,
|
||||||
|
"minecraft_version": minecraft_version,
|
||||||
|
"mod_version": mod_version
|
||||||
|
]
|
||||||
|
inputs.properties(properties)
|
||||||
|
filesMatching("META-INF/neoforge.mods.toml") {
|
||||||
|
expand properties
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.jar {
|
||||||
|
archiveClassifier = "dev"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.shadowJar {
|
||||||
archiveClassifier = "dev-all"
|
archiveClassifier = "dev-all"
|
||||||
destinationDirectory = layout.buildDirectory.dir("libs")
|
destinationDirectory = layout.buildDirectory.dir("libs")
|
||||||
configurations = [project.configurations.shadow]
|
configurations = [project.configurations.shadow]
|
||||||
relocate 'ca.spottedleaf.concurrentutil', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.concurrentutil'
|
relocate 'ca.spottedleaf.concurrentutil', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.concurrentutil'
|
||||||
|
relocate 'ca.spottedleaf.yamlconfig', 'ca.spottedleaf.moonrise.libs.ca.spottedleaf.yamlconfig'
|
||||||
relocate 'org.yaml.snakeyaml', 'ca.spottedleaf.moonrise.libs.org.yaml.snakeyaml'
|
relocate 'org.yaml.snakeyaml', 'ca.spottedleaf.moonrise.libs.org.yaml.snakeyaml'
|
||||||
}
|
}
|
||||||
|
|
||||||
Aw2At.setup(getProject(), tasks.remapJar)
|
tasks.register("productionJar", Zip.class) {
|
||||||
|
archiveClassifier = ""
|
||||||
|
archiveExtension = "jar"
|
||||||
|
destinationDirectory = layout.buildDirectory.dir("libs")
|
||||||
|
from(tasks.jarJar)
|
||||||
|
from(zipTree(tasks.shadowJar.archiveFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.assemble {
|
||||||
|
dependsOn tasks.productionJar
|
||||||
|
}
|
||||||
|
|
||||||
publishMods {
|
publishMods {
|
||||||
|
file = productionJar.archiveFile
|
||||||
modLoaders = ["neoforge"]
|
modLoaders = ["neoforge"]
|
||||||
|
|
||||||
modrinth {
|
modrinth {
|
||||||
@@ -65,3 +113,42 @@ publishMods {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
neoForge.runs.configureEach { cfg ->
|
||||||
|
runConfigCommon.systemProperties.get().each {
|
||||||
|
cfg.systemProperties.put it.key, it.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup a run with lithium for compatibility testing
|
||||||
|
neoForge {
|
||||||
|
runs {
|
||||||
|
lithiumClient {
|
||||||
|
client()
|
||||||
|
disableIdeRun()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks.withType(RunGameTask).configureEach {
|
||||||
|
if (name == "runLithiumClient") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
def out = gameDirectory.get().getAsFile().toPath().resolve("mods/lithium-tmp.jar")
|
||||||
|
doFirst {
|
||||||
|
Files.deleteIfExists(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def lithium = configurations.lithium
|
||||||
|
tasks.runLithiumClient {
|
||||||
|
def out = gameDirectory.get().getAsFile().toPath().resolve("mods/lithium-tmp.jar")
|
||||||
|
doFirst {
|
||||||
|
for (File file in lithium) {
|
||||||
|
Files.copy(file.toPath(), out, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doLast {
|
||||||
|
Files.deleteIfExists(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
loom.platform=neoforge
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package ca.spottedleaf.moonrise.neoforge;
|
package ca.spottedleaf.moonrise.neoforge;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.BaseChunkSystemHooks;
|
||||||
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.util.ConfigHolder;
|
import ca.spottedleaf.moonrise.common.util.ConfigHolder;
|
||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
@@ -34,10 +35,11 @@ import net.neoforged.neoforge.event.EventHooks;
|
|||||||
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
|
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
|
||||||
import net.neoforged.neoforge.event.level.ChunkDataEvent;
|
import net.neoforged.neoforge.event.level.ChunkDataEvent;
|
||||||
import net.neoforged.neoforge.event.level.ChunkEvent;
|
import net.neoforged.neoforge.event.level.ChunkEvent;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public final class NeoForgeHooks implements PlatformHooks {
|
public final class NeoForgeHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getBrand() {
|
public String getBrand() {
|
||||||
@@ -114,7 +116,12 @@ public final class NeoForgeHooks implements PlatformHooks {
|
|||||||
@Override
|
@Override
|
||||||
public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
|
public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
|
||||||
final List<Entity> into) {
|
final List<Entity> into) {
|
||||||
for (final PartEntity<?> part : world.getPartEntities()) {
|
final Collection<PartEntity<?>> parts = world.dragonParts();
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final PartEntity<?> part : parts) {
|
||||||
if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
|
if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
|
||||||
into.add(part);
|
into.add(part);
|
||||||
}
|
}
|
||||||
@@ -129,9 +136,18 @@ public final class NeoForgeHooks implements PlatformHooks {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final PartEntity<?> part : world.getPartEntities()) {
|
final Collection<PartEntity<?>> parts = world.dragonParts();
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final PartEntity<?> part : parts) {
|
||||||
|
if (!part.getBoundingBox().intersects(boundingBox)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final T casted = (T)entityTypeTest.tryCast(part);
|
final T casted = (T)entityTypeTest.tryCast(part);
|
||||||
if (casted != null && casted.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(casted))) {
|
if (casted != null && (predicate == null || predicate.test(casted))) {
|
||||||
into.add(casted);
|
into.add(casted);
|
||||||
if (into.size() >= maxCount) {
|
if (into.size() >= maxCount) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ side = "BOTH"
|
|||||||
[[dependencies.moonrise]]
|
[[dependencies.moonrise]]
|
||||||
modId = "minecraft"
|
modId = "minecraft"
|
||||||
type = "required"
|
type = "required"
|
||||||
versionRange = "(1.21.1,1.21.4)"
|
versionRange = "(1.21.3,1.21.5)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package ca.spottedleaf.moonrise.neoforge;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||||
|
|
||||||
|
class MixinAuditTest {
|
||||||
|
@Test
|
||||||
|
void auditMixins() {
|
||||||
|
final ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
|
try {
|
||||||
|
Thread.currentThread().setContextClassLoader(MixinAuditTest.class.getClassLoader());
|
||||||
|
MixinEnvironment.getCurrentEnvironment().audit();
|
||||||
|
} finally {
|
||||||
|
Thread.currentThread().setContextClassLoader(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ pluginManagement {
|
|||||||
maven {
|
maven {
|
||||||
name = 'jmp'
|
name = 'jmp'
|
||||||
url = 'https://repo.jpenilla.xyz/snapshots'
|
url = 'https://repo.jpenilla.xyz/snapshots'
|
||||||
mavenContent { snapshotsOnly() }
|
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = 'architectury'
|
name = 'architectury'
|
||||||
@@ -23,9 +22,10 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
|
||||||
id("xyz.jpenilla.quiet-architectury-loom") version "1.7.300" apply false
|
id("quiet-fabric-loom") version "1.9.312" apply false
|
||||||
id 'com.gradleup.shadow' version '8.3.0' apply false
|
id("net.neoforged.moddev") version "2.0.61-beta" apply false
|
||||||
|
id 'com.gradleup.shadow' version '8.3.5' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
@@ -48,3 +48,6 @@ include("fabric")
|
|||||||
findProject(":fabric").name = "Moonrise-Fabric"
|
findProject(":fabric").name = "Moonrise-Fabric"
|
||||||
include("neoforge")
|
include("neoforge")
|
||||||
findProject(":neoforge").name = "Moonrise-NeoForge"
|
findProject(":neoforge").name = "Moonrise-NeoForge"
|
||||||
|
|
||||||
|
// includeBuild("../YamlConfig") // Uncomment to use local YamlConfig
|
||||||
|
// includeBuild("../ConcurrentUtil") // Uncomment to use local ConcurrentUtil
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ca.spottedleaf.moonrise.common;
|
package ca.spottedleaf.moonrise.common;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.ChunkSystemHooks;
|
||||||
import com.mojang.datafixers.DSL;
|
import com.mojang.datafixers.DSL;
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@@ -8,7 +9,6 @@ import net.minecraft.server.level.ChunkHolder;
|
|||||||
import net.minecraft.server.level.GenerationChunkHolder;
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.util.datafix.DataFixTypes;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
@@ -24,7 +24,7 @@ import java.util.List;
|
|||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public interface PlatformHooks {
|
public interface PlatformHooks extends ChunkSystemHooks {
|
||||||
public static PlatformHooks get() {
|
public static PlatformHooks get() {
|
||||||
return Holder.INSTANCE;
|
return Holder.INSTANCE;
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,6 @@ public interface PlatformHooks {
|
|||||||
|
|
||||||
public void entityMove(final Entity entity, final long oldSection, final long newSection);
|
public void entityMove(final Entity entity, final long oldSection, final long newSection);
|
||||||
|
|
||||||
public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event);
|
|
||||||
|
|
||||||
public boolean configFixMC224294();
|
public boolean configFixMC224294();
|
||||||
|
|
||||||
public boolean configAutoConfigSendDistance();
|
public boolean configAutoConfigSendDistance();
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config;
|
|
||||||
|
|
||||||
public interface InitialiseHook {
|
|
||||||
|
|
||||||
public void initialise();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public abstract class TypeAdapter<T, S> {
|
|
||||||
|
|
||||||
public abstract T deserialize(final TypeAdapterRegistry registry, final Object input, final Type type);
|
|
||||||
|
|
||||||
public abstract S serialize(final TypeAdapterRegistry registry, final T value, final Type type);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.InitialiseHook;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.collection.CollectionTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.collection.ListTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.collection.SortedMapTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.BooleanTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.ByteTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.DoubleTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.FloatTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.IntegerTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.LongTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.ShortTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.StringTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.type.BigDecimalTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.type.BigIntegerTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.type.DurationTypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.annotation.Adaptable;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.annotation.Serializable;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.type.Duration;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class TypeAdapterRegistry {
|
|
||||||
|
|
||||||
private final Map<Class<?>, TypeAdapter<?, ?>> adapters = new HashMap<>();
|
|
||||||
{
|
|
||||||
this.adapters.put(boolean.class, BooleanTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(byte.class, ByteTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(short.class, ShortTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(int.class, IntegerTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(long.class, LongTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(float.class, FloatTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(double.class, DoubleTypeAdapter.INSTANCE);
|
|
||||||
|
|
||||||
this.adapters.put(Boolean.class, BooleanTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Byte.class, ByteTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Short.class, ShortTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Integer.class, IntegerTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Long.class, LongTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Float.class, FloatTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Double.class, DoubleTypeAdapter.INSTANCE);
|
|
||||||
|
|
||||||
this.adapters.put(String.class, StringTypeAdapter.INSTANCE);
|
|
||||||
|
|
||||||
this.adapters.put(Collection.class, CollectionTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(List.class, ListTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Map.class, SortedMapTypeAdapter.SORTED_CASE_INSENSITIVE);
|
|
||||||
this.adapters.put(LinkedHashMap.class, SortedMapTypeAdapter.SORTED_CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
this.adapters.put(BigInteger.class, BigIntegerTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(BigDecimal.class, BigDecimalTypeAdapter.INSTANCE);
|
|
||||||
this.adapters.put(Duration.class, DurationTypeAdapter.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeAdapter<?, ?> putAdapter(final Class<?> clazz, final TypeAdapter<?, ?> adapter) {
|
|
||||||
return this.adapters.put(clazz, adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeAdapter<?, ?> getAdapter(final Class<?> clazz) {
|
|
||||||
return this.adapters.get(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object deserialize(final Object input, final Type type) {
|
|
||||||
TypeAdapter<?, ?> adapter = null;
|
|
||||||
if (type instanceof Class<?> clazz) {
|
|
||||||
adapter = this.adapters.get(clazz);
|
|
||||||
}
|
|
||||||
if (adapter == null && (type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
adapter = this.adapters.get((Class<?>)parameterizedType.getRawType());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (adapter == null) {
|
|
||||||
throw new IllegalArgumentException("No adapter for " + input.getClass() + " with type " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((TypeAdapter)adapter).deserialize(this, input, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object serialize(final Object input, final Type type) {
|
|
||||||
TypeAdapter<?, ?> adapter = null;
|
|
||||||
if (type instanceof Class<?> clazz) {
|
|
||||||
adapter = this.adapters.get(clazz);
|
|
||||||
}
|
|
||||||
if (adapter == null && (type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
adapter = this.adapters.get((Class<?>)parameterizedType.getRawType());
|
|
||||||
}
|
|
||||||
if (adapter == null) {
|
|
||||||
adapter = this.adapters.get(input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (adapter == null) {
|
|
||||||
throw new IllegalArgumentException("No adapter for " + input.getClass() + " with type " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((TypeAdapter)adapter).serialize(this, input, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> TypeAdapter<T, Map<Object, Object>> makeAdapter(final Class<? extends T> clazz) throws Exception {
|
|
||||||
final TypeAdapter<T, Map<Object, Object>> ret = new AutoTypeAdapter<>(this, clazz);
|
|
||||||
|
|
||||||
this.putAdapter(clazz, ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void callInitialisers(final T object) {
|
|
||||||
if (object == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final TypeAdapter<?, ?> adapter = this.getAdapter(object.getClass());
|
|
||||||
|
|
||||||
if (!(adapter instanceof AutoTypeAdapter<?> autoTypeAdapter)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((AutoTypeAdapter<T>)autoTypeAdapter).callInitialisers(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class AutoTypeAdapter<T> extends TypeAdapter<T, Map<Object, Object>> {
|
|
||||||
|
|
||||||
private final TypeAdapterRegistry registry;
|
|
||||||
private final Constructor<? extends T> constructor;
|
|
||||||
private final SerializableField[] fields;
|
|
||||||
|
|
||||||
public AutoTypeAdapter(final TypeAdapterRegistry registry, final Class<? extends T> clazz) throws Exception {
|
|
||||||
this.registry = registry;
|
|
||||||
this.constructor = clazz.getConstructor();
|
|
||||||
this.fields = findSerializableFields(registry, clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TypeAdapter<?, ?> findOrMakeAdapter(final TypeAdapterRegistry registry, final Class<?> clazz) throws Exception {
|
|
||||||
final TypeAdapter<?, ?> ret = registry.getAdapter(clazz);
|
|
||||||
if (ret != null) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Annotation annotation : clazz.getAnnotations()) {
|
|
||||||
if (annotation instanceof Adaptable adaptable) {
|
|
||||||
return registry.makeAdapter(clazz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("No type adapter for " + clazz + " (Forgot @Adaptable?)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String makeSerializedKey(final String input) {
|
|
||||||
final StringBuilder ret = new StringBuilder();
|
|
||||||
|
|
||||||
for (final char c : input.toCharArray()) {
|
|
||||||
if (!Character.isUpperCase(c)) {
|
|
||||||
ret.append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ret.append('-');
|
|
||||||
ret.append(Character.toLowerCase(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static record SerializableField(
|
|
||||||
Field field,
|
|
||||||
boolean required,
|
|
||||||
String comment,
|
|
||||||
TypeAdapter<?, ?> adapter,
|
|
||||||
boolean serialize,
|
|
||||||
String serializedKey
|
|
||||||
) {}
|
|
||||||
|
|
||||||
private static SerializableField[] findSerializableFields(final TypeAdapterRegistry registry, Class<?> clazz) throws Exception {
|
|
||||||
final List<SerializableField> ret = new ArrayList<>();
|
|
||||||
do {
|
|
||||||
for (final Field field : clazz.getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
for (final Annotation annotation : field.getAnnotations()) {
|
|
||||||
if (!(annotation instanceof Serializable serializable)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final TypeAdapter<?, ?> adapter;
|
|
||||||
|
|
||||||
if (serializable.adapter() != TypeAdapter.class) {
|
|
||||||
adapter = serializable.adapter().getConstructor().newInstance();
|
|
||||||
} else {
|
|
||||||
adapter = findOrMakeAdapter(registry, field.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
String serializedKey = serializable.serializedKey();
|
|
||||||
if (serializedKey.isEmpty()) {
|
|
||||||
serializedKey = makeSerializedKey(field.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.add(new SerializableField(
|
|
||||||
field, serializable.required(), serializable.comment(), adapter,
|
|
||||||
serializable.serialize(), serializedKey
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((clazz = clazz.getSuperclass()) != Object.class);
|
|
||||||
|
|
||||||
ret.sort((final SerializableField c1, final SerializableField c2) -> {
|
|
||||||
return c1.serializedKey.compareTo(c2.serializedKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
return ret.toArray(new SerializableField[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(input instanceof Map<?,?> inputMap)) {
|
|
||||||
throw new IllegalArgumentException("Not a map type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final T ret = this.constructor.newInstance();
|
|
||||||
|
|
||||||
for (final SerializableField field : this.fields) {
|
|
||||||
final Object fieldValue = inputMap.get(field.serializedKey);
|
|
||||||
|
|
||||||
if (fieldValue == null) {
|
|
||||||
if (field.required) {
|
|
||||||
throw new IllegalArgumentException("Missing required field '" + field.serializedKey + "' in " + this.constructor.getDeclaringClass());
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
field.field.set(ret, field.adapter.deserialize(registry, fieldValue, field.field.getGenericType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Object, Object> serialize(final TypeAdapterRegistry registry, final T value, final Type type) {
|
|
||||||
final LinkedHashMap<Object, Object> ret = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
for (final SerializableField field : this.fields) {
|
|
||||||
if (!field.serialize) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Object fieldValue;
|
|
||||||
try {
|
|
||||||
fieldValue = field.field.get(value);
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldValue != null) {
|
|
||||||
ret.put(
|
|
||||||
field.comment.isBlank() ? field.serializedKey : new CommentedData(field.comment, field.serializedKey),
|
|
||||||
((TypeAdapter)field.adapter).serialize(
|
|
||||||
registry, fieldValue, field.field.getGenericType()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void callInitialisers(final T value) {
|
|
||||||
for (final SerializableField field : this.fields) {
|
|
||||||
final Object fieldValue;
|
|
||||||
try {
|
|
||||||
fieldValue = field.field.get(value);
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldValue instanceof InitialiseHook initialiseHook) {
|
|
||||||
initialiseHook.initialise();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.registry.callInitialisers(fieldValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class CommentedData {
|
|
||||||
|
|
||||||
public final String comment;
|
|
||||||
public final Object data;
|
|
||||||
|
|
||||||
public CommentedData(final String comment, final Object data) {
|
|
||||||
this.comment = comment;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.collection;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.primitive.StringTypeAdapter;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public final class CollectionTypeAdapter extends TypeAdapter<Collection<Object>, List<Object>> {
|
|
||||||
|
|
||||||
public static final CollectionTypeAdapter INSTANCE = new CollectionTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Object> deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
throw new IllegalArgumentException("Collection field must specify generic type");
|
|
||||||
}
|
|
||||||
final Type elementType = parameterizedType.getActualTypeArguments()[0];
|
|
||||||
if (input instanceof Collection<?> collection) {
|
|
||||||
final List<Object> ret = new ArrayList<>(collection.size());
|
|
||||||
|
|
||||||
for (final Object v : collection) {
|
|
||||||
ret.add(registry.deserialize(v, elementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Not a collection type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Object> serialize(final TypeAdapterRegistry registry, final Collection<Object> value, final Type type) {
|
|
||||||
final List<Object> ret = new ArrayList<>(value.size());
|
|
||||||
|
|
||||||
final Type elementType = type instanceof ParameterizedType parameterizedType ? parameterizedType.getActualTypeArguments()[0] : null;
|
|
||||||
|
|
||||||
for (final Object v : value) {
|
|
||||||
ret.add(registry.serialize(v, elementType == null ? v.getClass() : elementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.collection;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public final class ListTypeAdapter extends TypeAdapter<List<Object>, List<Object>> {
|
|
||||||
|
|
||||||
public static final ListTypeAdapter INSTANCE = new ListTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Object> deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
throw new IllegalArgumentException("Collection field must specify generic type");
|
|
||||||
}
|
|
||||||
final Type elementType = parameterizedType.getActualTypeArguments()[0];
|
|
||||||
if (input instanceof Collection<?> collection) {
|
|
||||||
final List<Object> ret = new ArrayList<>(collection.size());
|
|
||||||
|
|
||||||
for (final Object v : collection) {
|
|
||||||
ret.add(registry.deserialize(v, elementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Not a collection type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Object> serialize(final TypeAdapterRegistry registry, final List<Object> value, final Type type) {
|
|
||||||
final List<Object> ret = new ArrayList<>(value.size());
|
|
||||||
|
|
||||||
final Type elementType = type instanceof ParameterizedType parameterizedType ? parameterizedType.getActualTypeArguments()[0] : null;
|
|
||||||
|
|
||||||
for (final Object v : value) {
|
|
||||||
ret.add(registry.serialize(v, elementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.collection;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
public final class SortedMapTypeAdapter extends TypeAdapter<Map<String, Object>, Map<String, Object>> {
|
|
||||||
|
|
||||||
public static final SortedMapTypeAdapter SORTED_CASE_INSENSITIVE = new SortedMapTypeAdapter(String.CASE_INSENSITIVE_ORDER);
|
|
||||||
public static final SortedMapTypeAdapter SORTED_CASE_SENSITIVE = new SortedMapTypeAdapter(null);
|
|
||||||
|
|
||||||
private final Comparator<String> keyComparator;
|
|
||||||
|
|
||||||
public SortedMapTypeAdapter(final Comparator<String> keyComparator) {
|
|
||||||
this.keyComparator = keyComparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
throw new IllegalArgumentException("Collection field must specify generic type");
|
|
||||||
}
|
|
||||||
final Type valueType = parameterizedType.getActualTypeArguments()[1];
|
|
||||||
if (input instanceof Map<?,?> inputMap) {
|
|
||||||
final Map<String, Object> castedInput = (Map<String, Object>)inputMap;
|
|
||||||
|
|
||||||
final TreeMap<String, Object> ret = new TreeMap<>(this.keyComparator);
|
|
||||||
|
|
||||||
for (final Map.Entry<String, Object> entry : castedInput.entrySet()) {
|
|
||||||
ret.put(entry.getKey(), registry.deserialize(entry.getValue(), valueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
// transform to linked so that get() is O(1)
|
|
||||||
return new LinkedHashMap<>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a map type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> serialize(final TypeAdapterRegistry registry, final Map<String, Object> value, final Type type) {
|
|
||||||
final TreeMap<String, Object> ret = new TreeMap<>(this.keyComparator);
|
|
||||||
|
|
||||||
final Type valueType = type instanceof ParameterizedType parameterizedType ? parameterizedType.getActualTypeArguments()[1] : null;
|
|
||||||
|
|
||||||
for (final Map.Entry<String, Object> entry : value.entrySet()) {
|
|
||||||
ret.put(entry.getKey(), registry.serialize(entry.getValue(), valueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
// transform to linked so that get() is O(1)
|
|
||||||
return new LinkedHashMap<>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.collection;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class UnsortedMapTypeAdapter extends TypeAdapter<Map<String, Object>, Map<String, Object>> {
|
|
||||||
|
|
||||||
public static final UnsortedMapTypeAdapter INSTANCE = new UnsortedMapTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
throw new IllegalArgumentException("Collection field must specify generic type");
|
|
||||||
}
|
|
||||||
final Type valueType = parameterizedType.getActualTypeArguments()[1];
|
|
||||||
if (input instanceof Map<?,?> inputMap) {
|
|
||||||
final Map<String, Object> castedInput = (Map<String, Object>)inputMap;
|
|
||||||
|
|
||||||
final LinkedHashMap<String, Object> ret = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
for (final Map.Entry<String, Object> entry : castedInput.entrySet()) {
|
|
||||||
ret.put(entry.getKey(), registry.deserialize(entry.getValue(), valueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a map type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> serialize(final TypeAdapterRegistry registry, final Map<String, Object> value, final Type type) {
|
|
||||||
final LinkedHashMap<String, Object> ret = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
final Type valueType = type instanceof ParameterizedType parameterizedType ? parameterizedType.getActualTypeArguments()[1] : null;
|
|
||||||
|
|
||||||
for (final Map.Entry<String, Object> entry : value.entrySet()) {
|
|
||||||
ret.put(entry.getKey(), registry.serialize(entry.getValue(), valueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class BooleanTypeAdapter extends TypeAdapter<Boolean, Boolean> {
|
|
||||||
|
|
||||||
public static final BooleanTypeAdapter INSTANCE = new BooleanTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Boolean ret) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (input instanceof String str) {
|
|
||||||
if (str.equalsIgnoreCase("false")) {
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
if (str.equalsIgnoreCase("true")) {
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Not a boolean: " + str);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a boolean type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean serialize(final TypeAdapterRegistry registry, final Boolean value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class ByteTypeAdapter extends TypeAdapter<Byte, Byte> {
|
|
||||||
|
|
||||||
public static final ByteTypeAdapter INSTANCE = new ByteTypeAdapter();
|
|
||||||
|
|
||||||
private static Byte cast(final Object original, final long value) {
|
|
||||||
if (value < (long)Byte.MIN_VALUE || value > (long)Byte.MAX_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Byte value is out of range: " + original.toString());
|
|
||||||
}
|
|
||||||
return Byte.valueOf((byte)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Byte deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
// note: silently discard floating point significand
|
|
||||||
return cast(input, number instanceof BigInteger bigInteger ? bigInteger.longValueExact() : number.longValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return cast(input, (long)Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a byte type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Byte serialize(final TypeAdapterRegistry registry, final Byte value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class DoubleTypeAdapter extends TypeAdapter<Double, Double> {
|
|
||||||
|
|
||||||
public static final DoubleTypeAdapter INSTANCE = new DoubleTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
return Double.valueOf(number.doubleValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return Double.valueOf(Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a byte type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double serialize(final TypeAdapterRegistry registry, final Double value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class FloatTypeAdapter extends TypeAdapter<Float, Float> {
|
|
||||||
|
|
||||||
public static final FloatTypeAdapter INSTANCE = new FloatTypeAdapter();
|
|
||||||
|
|
||||||
private static Float cast(final Object original, final double value) {
|
|
||||||
if (value < -(double)Float.MAX_VALUE || value > (double)Float.MAX_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Byte value is out of range: " + original.toString());
|
|
||||||
}
|
|
||||||
// note: silently ignore precision loss
|
|
||||||
return Float.valueOf((float)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Float deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
return cast(input, number.doubleValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return cast(input, Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a byte type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Float serialize(final TypeAdapterRegistry registry, final Float value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class IntegerTypeAdapter extends TypeAdapter<Integer, Integer> {
|
|
||||||
|
|
||||||
public static final IntegerTypeAdapter INSTANCE = new IntegerTypeAdapter();
|
|
||||||
|
|
||||||
private static Integer cast(final Object original, final long value) {
|
|
||||||
if (value < (long)Integer.MIN_VALUE || value > (long)Integer.MAX_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Integer value is out of range: " + original.toString());
|
|
||||||
}
|
|
||||||
return Integer.valueOf((int)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
// note: silently discard floating point significand
|
|
||||||
return cast(input, number instanceof BigInteger bigInteger ? bigInteger.longValueExact() : number.longValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return cast(input, (long)Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not an integer type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer serialize(final TypeAdapterRegistry registry, final Integer value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class LongTypeAdapter extends TypeAdapter<Long, Long> {
|
|
||||||
|
|
||||||
public static final LongTypeAdapter INSTANCE = new LongTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
// note: silently discard floating point significand
|
|
||||||
return number instanceof BigInteger bigInteger ? bigInteger.longValueExact() : number.longValue();
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
try {
|
|
||||||
return Long.valueOf(Long.parseLong(string));
|
|
||||||
} catch (final NumberFormatException ex) {
|
|
||||||
return Long.valueOf((long)Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a long type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long serialize(final TypeAdapterRegistry registry, final Long value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class ShortTypeAdapter extends TypeAdapter<Short, Short> {
|
|
||||||
|
|
||||||
public static final ShortTypeAdapter INSTANCE = new ShortTypeAdapter();
|
|
||||||
|
|
||||||
private static Short cast(final Object original, final long value) {
|
|
||||||
if (value < (long)Short.MIN_VALUE || value > (long)Short.MAX_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Short value is out of range: " + original.toString());
|
|
||||||
}
|
|
||||||
return Short.valueOf((short)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Short deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
// note: silently discard floating point significand
|
|
||||||
return cast(input, number instanceof BigInteger bigInteger ? bigInteger.longValueExact() : number.longValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return cast(input, (long)Double.parseDouble(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not a short type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Short serialize(final TypeAdapterRegistry registry, final Short value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.primitive;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class StringTypeAdapter extends TypeAdapter<String, String> {
|
|
||||||
|
|
||||||
public static final StringTypeAdapter INSTANCE = new StringTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Boolean bool) {
|
|
||||||
return String.valueOf(bool.booleanValue());
|
|
||||||
}
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
return number.toString();
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Not a string type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize(final TypeAdapterRegistry registry, final String value, final Type type) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.type;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class BigDecimalTypeAdapter extends TypeAdapter<BigDecimal, String> {
|
|
||||||
|
|
||||||
public static final BigDecimalTypeAdapter INSTANCE = new BigDecimalTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigDecimal deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
// safest to catch all number impls is to use toString
|
|
||||||
return new BigDecimal(number.toString());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return new BigDecimal(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not an BigDecimal type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize(final TypeAdapterRegistry registry, final BigDecimal value, final Type type) {
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.type;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public final class BigIntegerTypeAdapter extends TypeAdapter<BigInteger, String> {
|
|
||||||
|
|
||||||
public static final BigIntegerTypeAdapter INSTANCE = new BigIntegerTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigInteger deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof Number number) {
|
|
||||||
if (number instanceof BigInteger bigInteger) {
|
|
||||||
return bigInteger;
|
|
||||||
}
|
|
||||||
// note: silently discard floating point significand
|
|
||||||
if (number instanceof BigDecimal bigDecimal) {
|
|
||||||
return bigDecimal.toBigInteger();
|
|
||||||
}
|
|
||||||
|
|
||||||
return BigInteger.valueOf(number.longValue());
|
|
||||||
}
|
|
||||||
if (input instanceof String string) {
|
|
||||||
return new BigDecimal(string).toBigInteger();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not an BigInteger type: " + input.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize(final TypeAdapterRegistry registry, final BigInteger value, final Type type) {
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.adapter.type;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.type.Duration;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class DurationTypeAdapter extends TypeAdapter<Duration, String> {
|
|
||||||
|
|
||||||
public static final DurationTypeAdapter INSTANCE = new DurationTypeAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Duration deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (!(input instanceof String string)) {
|
|
||||||
throw new IllegalArgumentException("Not a string: " + input.getClass());
|
|
||||||
}
|
|
||||||
return Duration.parse(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize(final TypeAdapterRegistry registry, final Duration value, final Type type) {
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation used on a class to indicate that its type adapter may automatically be generated. The class must have
|
|
||||||
* a public no-args constructor.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public @interface Adaptable {
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.annotation;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation indicating that a field should be deserialized or serialized from the config.
|
|
||||||
* By default, this annotation is not assumed.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
public @interface Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this field is required to be present in the config. If the field is not present,
|
|
||||||
* and {@code required = true}, then an exception will be thrown during deserialization. If {@code required = false}
|
|
||||||
* and the field is not present, then the field value will remain unmodified.
|
|
||||||
*/
|
|
||||||
public boolean required() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The comment to apply before the element when serializing.
|
|
||||||
*/
|
|
||||||
public String comment() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter override class. The class must have a public no-args constructor.
|
|
||||||
*/
|
|
||||||
public Class<? extends TypeAdapter> adapter() default TypeAdapter.class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to serialize the value to the config.
|
|
||||||
*/
|
|
||||||
public boolean serialize() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When not empty, this value overrides the auto generated serialized key in the config.
|
|
||||||
*/
|
|
||||||
public String serializedKey() default "";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.config;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
|
||||||
import org.yaml.snakeyaml.LoaderOptions;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
import org.yaml.snakeyaml.comments.CommentLine;
|
|
||||||
import org.yaml.snakeyaml.comments.CommentType;
|
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
|
||||||
import org.yaml.snakeyaml.nodes.Node;
|
|
||||||
import org.yaml.snakeyaml.representer.Represent;
|
|
||||||
import org.yaml.snakeyaml.representer.Representer;
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.AtomicMoveNotSupportedException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
public final class YamlConfig<T> {
|
|
||||||
|
|
||||||
public final TypeAdapterRegistry typeAdapters;
|
|
||||||
|
|
||||||
private final Class<? extends T> clazz;
|
|
||||||
|
|
||||||
public volatile T config;
|
|
||||||
|
|
||||||
private final Yaml yaml;
|
|
||||||
private final LoaderOptions loaderOptions;
|
|
||||||
private final DumperOptions dumperOptions;
|
|
||||||
|
|
||||||
public YamlConfig(final Class<? extends T> clazz, final T dfl) throws Exception {
|
|
||||||
this(clazz, dfl, new TypeAdapterRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
public YamlConfig(final Class<? extends T> clazz, final T dfl, final TypeAdapterRegistry registry) throws Exception {
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.config = dfl;
|
|
||||||
this.typeAdapters = registry;
|
|
||||||
this.typeAdapters.makeAdapter(clazz);
|
|
||||||
|
|
||||||
final LoaderOptions loaderOptions = new LoaderOptions();
|
|
||||||
loaderOptions.setProcessComments(true);
|
|
||||||
|
|
||||||
final DumperOptions dumperOptions = new DumperOptions();
|
|
||||||
dumperOptions.setProcessComments(true);
|
|
||||||
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
|
||||||
|
|
||||||
this.loaderOptions = loaderOptions;
|
|
||||||
this.dumperOptions = dumperOptions;
|
|
||||||
this.yaml = new Yaml(new YamlConstructor(loaderOptions), new YamlRepresenter(dumperOptions), dumperOptions, loaderOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load(final File file) throws IOException {
|
|
||||||
try (final InputStream is = new BufferedInputStream(new FileInputStream(file))) {
|
|
||||||
this.load(is);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load(final InputStream is) throws IOException {
|
|
||||||
final Object serialized = this.yaml.load(new InputStreamReader(is, StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
this.config = (T)this.typeAdapters.deserialize(serialized, this.clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(final File file) throws IOException {
|
|
||||||
this.save(file, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(final File file, final String header) throws IOException {
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
throw new IOException("File is a directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
final File parent = file.getParentFile();
|
|
||||||
if (parent != null) {
|
|
||||||
parent.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
final File tmp = new File(parent, file.getName() + ".tmp");
|
|
||||||
tmp.delete();
|
|
||||||
tmp.createNewFile();
|
|
||||||
try {
|
|
||||||
try (final OutputStream os = new BufferedOutputStream(new FileOutputStream(tmp))) {
|
|
||||||
this.save(os, header);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Files.move(tmp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
|
||||||
} catch (final AtomicMoveNotSupportedException ex) {
|
|
||||||
Files.move(tmp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
tmp.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(final OutputStream os) throws IOException {
|
|
||||||
os.write(this.saveToString().getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(final OutputStream os, final String header) throws IOException {
|
|
||||||
os.write(this.saveToString(header).getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String saveToString() {
|
|
||||||
return this.yaml.dump(this.typeAdapters.serialize(this.config, this.clazz));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String saveToString(final String header) {
|
|
||||||
if (header.isBlank()) {
|
|
||||||
return this.saveToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder ret = new StringBuilder();
|
|
||||||
final String lineBreak = this.dumperOptions.getLineBreak().getString();
|
|
||||||
|
|
||||||
for (final String line : header.split("\n")) {
|
|
||||||
ret.append("# ").append(line.trim()).append(lineBreak);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.append(lineBreak);
|
|
||||||
|
|
||||||
return ret.append(this.saveToString()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void callInitialisers() {
|
|
||||||
this.typeAdapters.callInitialisers(this.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class YamlConstructor extends Constructor {
|
|
||||||
|
|
||||||
public YamlConstructor(final LoaderOptions loadingConfig) {
|
|
||||||
super(loadingConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class YamlRepresenter extends Representer {
|
|
||||||
|
|
||||||
public YamlRepresenter(final DumperOptions options) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
this.representers.put(TypeAdapterRegistry.CommentedData.class, new CommentedDataRepresenter());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class CommentedDataRepresenter implements Represent {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node representData(final Object data0) {
|
|
||||||
final TypeAdapterRegistry.CommentedData commentedData = (TypeAdapterRegistry.CommentedData)data0;
|
|
||||||
|
|
||||||
final Node node = YamlRepresenter.this.representData(commentedData.data);
|
|
||||||
|
|
||||||
final List<CommentLine> comments = new ArrayList<>();
|
|
||||||
|
|
||||||
for (final String line : commentedData.comment.split("\n")) {
|
|
||||||
comments.add(new CommentLine(null, null, " ".concat(line.trim()), CommentType.BLOCK));
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setBlockComments(comments);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.moonrise;
|
package ca.spottedleaf.moonrise.common.config.moonrise;
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.InitialiseHook;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.annotation.Adaptable;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.ui.ClothConfig;
|
import ca.spottedleaf.moonrise.common.config.ui.ClothConfig;
|
||||||
import ca.spottedleaf.moonrise.common.config.annotation.Serializable;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.type.Duration;
|
|
||||||
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
|
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler;
|
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler;
|
||||||
|
import ca.spottedleaf.yamlconfig.InitialiseHook;
|
||||||
|
import ca.spottedleaf.yamlconfig.annotation.Adaptable;
|
||||||
|
import ca.spottedleaf.yamlconfig.annotation.Serializable;
|
||||||
|
import ca.spottedleaf.yamlconfig.type.Duration;
|
||||||
|
|
||||||
@Adaptable
|
@Adaptable
|
||||||
public final class MoonriseConfig {
|
public final class MoonriseConfig {
|
||||||
@@ -251,4 +251,21 @@ public final class MoonriseConfig {
|
|||||||
)
|
)
|
||||||
public boolean fixMC159283 = false;
|
public boolean fixMC159283 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public Misc misc = new Misc();
|
||||||
|
|
||||||
|
@Adaptable
|
||||||
|
public static final class Misc {
|
||||||
|
|
||||||
|
@Serializable(
|
||||||
|
serializedKey = "immediately-close-loading-screen",
|
||||||
|
comment = """
|
||||||
|
Whether the loading screen should be closed immediately when joining servers/SP worlds.
|
||||||
|
This will let you in game faster, but may result in getting in game before enough chunks are
|
||||||
|
loaded for rendering.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
public boolean immediatelyCloseLoadingScreen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.moonrise.adapter;
|
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapter;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.moonrise.type.DefaultedValue;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public final class DefaultedTypeAdapter extends TypeAdapter<DefaultedValue<?>, Object> {
|
|
||||||
|
|
||||||
private static final String DEFAULT_STRING = "default";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DefaultedValue<?> deserialize(final TypeAdapterRegistry registry, final Object input, final Type type) {
|
|
||||||
if (input instanceof String string && string.equalsIgnoreCase(DEFAULT_STRING)) {
|
|
||||||
return new DefaultedValue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(type instanceof ParameterizedType parameterizedType)) {
|
|
||||||
throw new IllegalArgumentException("DefaultedValue field must specify generic type");
|
|
||||||
}
|
|
||||||
final Type valueType = parameterizedType.getActualTypeArguments()[0];
|
|
||||||
|
|
||||||
return new DefaultedValue<>(registry.deserialize(input, valueType));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object serialize(final TypeAdapterRegistry registry, final DefaultedValue<?> value, final Type type) {
|
|
||||||
final Object raw = value.getValueRaw();
|
|
||||||
if (raw == null) {
|
|
||||||
return DEFAULT_STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Type valueType = type instanceof ParameterizedType parameterizedType ? parameterizedType.getActualTypeArguments()[0] : null;
|
|
||||||
|
|
||||||
return registry.serialize(raw, valueType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.moonrise.type;
|
|
||||||
|
|
||||||
public final class DefaultedValue<T> {
|
|
||||||
|
|
||||||
private final T value;
|
|
||||||
|
|
||||||
public DefaultedValue() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultedValue(final T value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getValueRaw() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getOrDefault(final T dfl) {
|
|
||||||
return this.value != null ? this.value : dfl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.config.type;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
public final class Duration {
|
|
||||||
|
|
||||||
private final String string;
|
|
||||||
private final long timeNS;
|
|
||||||
|
|
||||||
private Duration(final String string, final long timeNS) {
|
|
||||||
this.string = string;
|
|
||||||
this.timeNS = timeNS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Duration parse(final String value) {
|
|
||||||
if (value.length() < 2) {
|
|
||||||
throw new IllegalArgumentException("Invalid duration: " + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
final char last = value.charAt(value.length() - 1);
|
|
||||||
|
|
||||||
final long multiplier;
|
|
||||||
|
|
||||||
switch (last) {
|
|
||||||
case 's': {
|
|
||||||
multiplier = (1000L * 1000L * 1000L) * 1L;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 't': {
|
|
||||||
multiplier = (1000L * 1000L * 1000L) / 20L;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'm': {
|
|
||||||
multiplier = (1000L * 1000L * 1000L) * 60L;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'h': {
|
|
||||||
multiplier = (1000L * 1000L * 1000L) * 60L * 60L;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'd': {
|
|
||||||
multiplier = (1000L * 1000L * 1000L) * 24L * 60L * 60L;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new IllegalArgumentException("Duration must end with one of: [s, t, m, h, d]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final BigDecimal parsed = new BigDecimal(value.substring(0, value.length() - 1))
|
|
||||||
.multiply(new BigDecimal(multiplier));
|
|
||||||
|
|
||||||
return new Duration(value, parsed.toBigInteger().longValueExact());
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeNS() {
|
|
||||||
return this.timeNS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeMS() {
|
|
||||||
return this.timeNS / (1000L * 1000L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeS() {
|
|
||||||
return this.timeNS / (1000L * 1000L * 1000L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeTicks() {
|
|
||||||
return this.timeNS / ((1000L * 1000L * 1000L) / (20L));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package ca.spottedleaf.moonrise.common.misc;
|
package ca.spottedleaf.moonrise.common.misc;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
||||||
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants;
|
import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants;
|
||||||
@@ -121,8 +121,8 @@ public final class NearbyPlayers {
|
|||||||
players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE);
|
players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE);
|
||||||
players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE);
|
players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE);
|
||||||
players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE);
|
players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE);
|
||||||
players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player));
|
players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, PlatformHooks.get().getTickViewDistance(player));
|
||||||
players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getLoadViewDistance(player));
|
players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, PlatformHooks.get().getViewDistance(player));
|
||||||
players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration
|
players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,121 +1,125 @@
|
|||||||
package ca.spottedleaf.moonrise.common.util;
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
import ca.spottedleaf.concurrentutil.util.Priority;
|
import ca.spottedleaf.concurrentutil.util.Priority;
|
||||||
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
|
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache;
|
import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
|
||||||
import com.mojang.logging.LogUtils;
|
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.server.level.FullChunkStatus;
|
import net.minecraft.server.level.FullChunkStatus;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public final class ChunkSystem {
|
public abstract class BaseChunkSystemHooks implements ChunkSystemHooks {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
@Override
|
||||||
|
public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
|
||||||
public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
|
|
||||||
scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
|
scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
|
@Override
|
||||||
|
public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
|
||||||
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority);
|
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
|
@Override
|
||||||
final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
|
public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
|
||||||
final Consumer<ChunkAccess> onComplete) {
|
final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
|
||||||
|
final Consumer<ChunkAccess> onComplete) {
|
||||||
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete);
|
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
|
@Override
|
||||||
final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
|
public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
|
||||||
|
final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
|
||||||
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
|
@Override
|
||||||
final FullChunkStatus toStatus, final boolean addTicket,
|
public void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
|
||||||
final Priority priority, final Consumer<LevelChunk> onComplete) {
|
final FullChunkStatus toStatus, final boolean addTicket,
|
||||||
|
final Priority priority, final Consumer<LevelChunk> onComplete) {
|
||||||
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
|
@Override
|
||||||
|
public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
|
||||||
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
|
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
|
@Override
|
||||||
|
public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
|
||||||
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
|
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getVisibleChunkHolderCount(final ServerLevel level) {
|
@Override
|
||||||
|
public int getVisibleChunkHolderCount(final ServerLevel level) {
|
||||||
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
|
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getUpdatingChunkHolderCount(final ServerLevel level) {
|
@Override
|
||||||
|
public int getUpdatingChunkHolderCount(final ServerLevel level) {
|
||||||
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
|
return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasAnyChunkHolders(final ServerLevel level) {
|
@Override
|
||||||
|
public boolean hasAnyChunkHolders(final ServerLevel level) {
|
||||||
return getUpdatingChunkHolderCount(level) != 0;
|
return getUpdatingChunkHolderCount(level) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) {
|
@Override
|
||||||
if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) {
|
public void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
|
||||||
// Update progress listener for LevelLoadingScreen
|
// Update progress listener for LevelLoadingScreen
|
||||||
final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener;
|
final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener;
|
||||||
if (progressListener != null) {
|
if (progressListener != null) {
|
||||||
ChunkSystem.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> {
|
this.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> {
|
||||||
progressListener.onStatusChange(holder.getPos(), null);
|
progressListener.onStatusChange(holder.getPos(), null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
|
((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
|
||||||
.moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk);
|
.moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().remove(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().remove(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
|
((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
|
||||||
.moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null);
|
.moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().add(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().add(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) {
|
if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) {
|
||||||
chunk.postProcessGeneration((ServerLevel)chunk.getLevel());
|
chunk.postProcessGeneration((ServerLevel)chunk.getLevel());
|
||||||
@@ -125,52 +129,60 @@ public final class ChunkSystem {
|
|||||||
((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
|
((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
|
((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().add(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().add(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
@Override
|
||||||
|
public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||||
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().remove(
|
((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().remove(
|
||||||
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
|
@Override
|
||||||
|
public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSendViewDistance(final ServerPlayer player) {
|
@Override
|
||||||
|
public int getSendViewDistance(final ServerPlayer player) {
|
||||||
return RegionizedPlayerChunkLoader.getAPISendViewDistance(player);
|
return RegionizedPlayerChunkLoader.getAPISendViewDistance(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLoadViewDistance(final ServerPlayer player) {
|
@Override
|
||||||
return RegionizedPlayerChunkLoader.getLoadViewDistance(player);
|
public int getViewDistance(final ServerPlayer player) {
|
||||||
|
return RegionizedPlayerChunkLoader.getAPIViewDistance(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTickViewDistance(final ServerPlayer player) {
|
@Override
|
||||||
|
public int getTickViewDistance(final ServerPlayer player) {
|
||||||
return RegionizedPlayerChunkLoader.getAPITickViewDistance(player);
|
return RegionizedPlayerChunkLoader.getAPITickViewDistance(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
@Override
|
||||||
|
public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
||||||
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player);
|
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
@Override
|
||||||
|
public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
||||||
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player);
|
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateMaps(final ServerLevel world, final ServerPlayer player) {
|
@Override
|
||||||
|
public void updateMaps(final ServerLevel world, final ServerPlayer player) {
|
||||||
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player);
|
((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChunkSystem() {}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
|
import ca.spottedleaf.concurrentutil.util.Priority;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.FullChunkStatus;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface ChunkSystemHooks {
|
||||||
|
|
||||||
|
public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run);
|
||||||
|
|
||||||
|
public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority);
|
||||||
|
|
||||||
|
public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
|
||||||
|
final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
|
||||||
|
final Consumer<ChunkAccess> onComplete);
|
||||||
|
|
||||||
|
public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
|
||||||
|
final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete);
|
||||||
|
|
||||||
|
public void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
|
||||||
|
final FullChunkStatus toStatus, final boolean addTicket,
|
||||||
|
final Priority priority, final Consumer<LevelChunk> onComplete);
|
||||||
|
|
||||||
|
public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level);
|
||||||
|
|
||||||
|
public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level);
|
||||||
|
|
||||||
|
public int getVisibleChunkHolderCount(final ServerLevel level);
|
||||||
|
|
||||||
|
public int getUpdatingChunkHolderCount(final ServerLevel level);
|
||||||
|
|
||||||
|
public boolean hasAnyChunkHolders(final ServerLevel level);
|
||||||
|
|
||||||
|
public boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event);
|
||||||
|
|
||||||
|
public void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder);
|
||||||
|
|
||||||
|
public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ);
|
||||||
|
|
||||||
|
public int getSendViewDistance(final ServerPlayer player);
|
||||||
|
|
||||||
|
public int getViewDistance(final ServerPlayer player);
|
||||||
|
|
||||||
|
public int getTickViewDistance(final ServerPlayer player);
|
||||||
|
|
||||||
|
public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player);
|
||||||
|
|
||||||
|
public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player);
|
||||||
|
|
||||||
|
public void updateMaps(final ServerLevel world, final ServerPlayer player);
|
||||||
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package ca.spottedleaf.moonrise.common.util;
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.config.YamlConfig;
|
|
||||||
import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig;
|
import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig;
|
||||||
import ca.spottedleaf.moonrise.common.config.moonrise.adapter.DefaultedTypeAdapter;
|
import ca.spottedleaf.yamlconfig.adapter.TypeAdapterRegistry;
|
||||||
import ca.spottedleaf.moonrise.common.config.moonrise.type.DefaultedValue;
|
import ca.spottedleaf.yamlconfig.config.YamlConfig;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -18,8 +16,6 @@ public final class ConfigHolder {
|
|||||||
private static final TypeAdapterRegistry CONFIG_ADAPTERS = new TypeAdapterRegistry();
|
private static final TypeAdapterRegistry CONFIG_ADAPTERS = new TypeAdapterRegistry();
|
||||||
private static final YamlConfig<MoonriseConfig> CONFIG;
|
private static final YamlConfig<MoonriseConfig> CONFIG;
|
||||||
static {
|
static {
|
||||||
CONFIG_ADAPTERS.putAdapter(DefaultedValue.class, new DefaultedTypeAdapter());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CONFIG = new YamlConfig<>(MoonriseConfig.class, new MoonriseConfig(), CONFIG_ADAPTERS);
|
CONFIG = new YamlConfig<>(MoonriseConfig.class, new MoonriseConfig(), CONFIG_ADAPTERS);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
@@ -52,14 +48,6 @@ public final class ConfigHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean reloadConfig() {
|
public static boolean reloadConfig() {
|
||||||
final boolean ret = reloadConfig0();
|
|
||||||
|
|
||||||
CONFIG.callInitialisers();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean reloadConfig0() {
|
|
||||||
synchronized (CONFIG) {
|
synchronized (CONFIG) {
|
||||||
if (CONFIG_FILE.exists()) {
|
if (CONFIG_FILE.exists()) {
|
||||||
try {
|
try {
|
||||||
@@ -70,6 +58,8 @@ public final class ConfigHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CONFIG.callInitialisers();
|
||||||
|
|
||||||
// write back any changes, or create if needed
|
// write back any changes, or create if needed
|
||||||
return saveConfig();
|
return saveConfig();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ca.spottedleaf.moonrise.common.util;
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.Strictness;
|
||||||
import com.google.gson.internal.Streams;
|
import com.google.gson.internal.Streams;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -16,7 +17,7 @@ public final class JsonUtil {
|
|||||||
final StringWriter stringWriter = new StringWriter();
|
final StringWriter stringWriter = new StringWriter();
|
||||||
final JsonWriter jsonWriter = new JsonWriter(stringWriter);
|
final JsonWriter jsonWriter = new JsonWriter(stringWriter);
|
||||||
jsonWriter.setIndent(" ");
|
jsonWriter.setIndent(" ");
|
||||||
jsonWriter.setLenient(false);
|
jsonWriter.setStrictness(Strictness.LENIENT);
|
||||||
Streams.write(element, jsonWriter);
|
Streams.write(element, jsonWriter);
|
||||||
|
|
||||||
final String jsonString = stringWriter.toString();
|
final String jsonString = stringWriter.toString();
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package ca.spottedleaf.moonrise.common.util;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoid costly CAS of superclass
|
|
||||||
*/
|
|
||||||
public final class SimpleRandom extends LegacyRandomSource {
|
|
||||||
|
|
||||||
private static final long MULTIPLIER = 25214903917L;
|
|
||||||
private static final long ADDEND = 11L;
|
|
||||||
private static final int BITS = 48;
|
|
||||||
private static final long MASK = (1L << BITS) - 1;
|
|
||||||
|
|
||||||
private long value;
|
|
||||||
|
|
||||||
public SimpleRandom(final long seed) {
|
|
||||||
super(0L);
|
|
||||||
this.value = seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSeed(final long seed) {
|
|
||||||
this.value = (seed ^ MULTIPLIER) & MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long advanceSeed() {
|
|
||||||
return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int next(final int bits) {
|
|
||||||
return (int)(this.advanceSeed() >>> (BITS - bits));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int nextInt() {
|
|
||||||
final long seed = this.advanceSeed();
|
|
||||||
return (int)(seed >>> (BITS - Integer.SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int nextInt(final int bound) {
|
|
||||||
if (bound <= 0) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
|
|
||||||
final long value = this.advanceSeed() >>> (BITS - Integer.SIZE);
|
|
||||||
return (int)((value * (long)bound) >>> Integer.SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.levelgen.BitRandomSource;
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian;
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid costly CAS of superclass + division in nextInt
|
||||||
|
*/
|
||||||
|
public final class SimpleThreadUnsafeRandom implements BitRandomSource {
|
||||||
|
|
||||||
|
private static final long MULTIPLIER = 25214903917L;
|
||||||
|
private static final long ADDEND = 11L;
|
||||||
|
private static final int BITS = 48;
|
||||||
|
private static final long MASK = (1L << BITS) - 1L;
|
||||||
|
|
||||||
|
private long value;
|
||||||
|
private final MarsagliaPolarGaussian gaussianSource = new MarsagliaPolarGaussian(this);
|
||||||
|
|
||||||
|
public SimpleThreadUnsafeRandom(final long seed) {
|
||||||
|
this.setSeed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSeed(final long seed) {
|
||||||
|
this.value = (seed ^ MULTIPLIER) & MASK;
|
||||||
|
this.gaussianSource.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long advanceSeed() {
|
||||||
|
return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int next(final int bits) {
|
||||||
|
return (int)(this.advanceSeed() >>> (BITS - bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nextInt() {
|
||||||
|
final long seed = this.advanceSeed();
|
||||||
|
return (int)(seed >>> (BITS - Integer.SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nextInt(final int bound) {
|
||||||
|
if (bound <= 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
|
||||||
|
final long value = this.advanceSeed() >>> (BITS - Integer.SIZE);
|
||||||
|
return (int)((value * (long)bound) >>> Integer.SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double nextGaussian() {
|
||||||
|
return this.gaussianSource.nextGaussian();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fork() {
|
||||||
|
return new SimpleThreadUnsafeRandom(this.nextLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PositionalRandomFactory forkPositional() {
|
||||||
|
return new SimpleRandomPositionalFactory(this.nextLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class SimpleRandomPositionalFactory implements PositionalRandomFactory {
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
|
||||||
|
public SimpleRandomPositionalFactory(final long seed) {
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSeed() {
|
||||||
|
return this.seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fromHashOf(final String string) {
|
||||||
|
return new SimpleThreadUnsafeRandom((long)string.hashCode() ^ this.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fromSeed(final long seed) {
|
||||||
|
return new SimpleThreadUnsafeRandom(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource at(final int x, final int y, final int z) {
|
||||||
|
return new SimpleThreadUnsafeRandom(Mth.getSeed(x, y, z) ^ this.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parityConfigString(final StringBuilder stringBuilder) {
|
||||||
|
stringBuilder.append("SimpleRandomPositionalFactory{").append(this.seed).append('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.levelgen.BitRandomSource;
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian;
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid costly CAS of superclass
|
||||||
|
*/
|
||||||
|
public final class ThreadUnsafeRandom implements BitRandomSource {
|
||||||
|
|
||||||
|
private static final long MULTIPLIER = 25214903917L;
|
||||||
|
private static final long ADDEND = 11L;
|
||||||
|
private static final int BITS = 48;
|
||||||
|
private static final long MASK = (1L << BITS) - 1L;
|
||||||
|
|
||||||
|
private long value;
|
||||||
|
private final MarsagliaPolarGaussian gaussianSource = new MarsagliaPolarGaussian(this);
|
||||||
|
|
||||||
|
public ThreadUnsafeRandom(final long seed) {
|
||||||
|
this.setSeed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSeed(final long seed) {
|
||||||
|
this.value = (seed ^ MULTIPLIER) & MASK;
|
||||||
|
this.gaussianSource.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long advanceSeed() {
|
||||||
|
return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int next(final int bits) {
|
||||||
|
return (int)(this.advanceSeed() >>> (BITS - bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nextInt() {
|
||||||
|
final long seed = this.advanceSeed();
|
||||||
|
return (int)(seed >>> (BITS - Integer.SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double nextGaussian() {
|
||||||
|
return this.gaussianSource.nextGaussian();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fork() {
|
||||||
|
return new ThreadUnsafeRandom(this.nextLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PositionalRandomFactory forkPositional() {
|
||||||
|
return new ThreadUnsafeRandomPositionalFactory(this.nextLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ThreadUnsafeRandomPositionalFactory implements PositionalRandomFactory {
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
|
||||||
|
public ThreadUnsafeRandomPositionalFactory(final long seed) {
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSeed() {
|
||||||
|
return this.seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fromHashOf(final String string) {
|
||||||
|
return new ThreadUnsafeRandom((long)string.hashCode() ^ this.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fromSeed(final long seed) {
|
||||||
|
return new ThreadUnsafeRandom(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource at(final int x, final int y, final int z) {
|
||||||
|
return new ThreadUnsafeRandom(Mth.getSeed(x, y, z) ^ this.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parityConfigString(final StringBuilder stringBuilder) {
|
||||||
|
stringBuilder.append("ThreadUnsafeRandomPositionalFactory{").append(this.seed).append('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package ca.spottedleaf.moonrise.mixin.chunk_system;
|
package ca.spottedleaf.moonrise.mixin.chunk_system;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
||||||
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
@@ -499,7 +499,7 @@ abstract class ChunkMapMixin extends ChunkStorage implements ChunkSystemChunkMap
|
|||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public int getPlayerViewDistance(final ServerPlayer player) {
|
public int getPlayerViewDistance(final ServerPlayer player) {
|
||||||
return ChunkSystem.getSendViewDistance(player);
|
return PlatformHooks.get().getSendViewDistance(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -597,7 +597,7 @@ abstract class ChunkMapMixin extends ChunkStorage implements ChunkSystemChunkMap
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void avoidUpdateChunkTrackingInUpdate(final ChunkMap instance, final ServerPlayer serverPlayer) {
|
private void avoidUpdateChunkTrackingInUpdate(final ChunkMap instance, final ServerPlayer serverPlayer) {
|
||||||
ChunkSystem.addPlayerToDistanceMaps(this.level, serverPlayer);
|
PlatformHooks.get().addPlayerToDistanceMaps(this.level, serverPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -627,7 +627,7 @@ abstract class ChunkMapMixin extends ChunkStorage implements ChunkSystemChunkMap
|
|||||||
)
|
)
|
||||||
private void avoidApplyChunkTrackingViewInUpdate(final ChunkMap instance, final ServerPlayer serverPlayer,
|
private void avoidApplyChunkTrackingViewInUpdate(final ChunkMap instance, final ServerPlayer serverPlayer,
|
||||||
final ChunkTrackingView chunkTrackingView) {
|
final ChunkTrackingView chunkTrackingView) {
|
||||||
ChunkSystem.removePlayerFromDistanceMaps(this.level, serverPlayer);
|
PlatformHooks.get().removePlayerFromDistanceMaps(this.level, serverPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -641,7 +641,7 @@ abstract class ChunkMapMixin extends ChunkStorage implements ChunkSystemChunkMap
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void updateMapsHook(final ServerPlayer player, final CallbackInfo ci) {
|
private void updateMapsHook(final ServerPlayer player, final CallbackInfo ci) {
|
||||||
ChunkSystem.updateMaps(this.level, player);
|
PlatformHooks.get().updateMaps(this.level, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ca.spottedleaf.moonrise.mixin.chunk_system;
|
package ca.spottedleaf.moonrise.mixin.chunk_system;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager;
|
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager;
|
||||||
@@ -13,6 +14,7 @@ import net.minecraft.server.level.ThrottlingChunkTaskDispatcher;
|
|||||||
import net.minecraft.server.level.Ticket;
|
import net.minecraft.server.level.Ticket;
|
||||||
import net.minecraft.server.level.TicketType;
|
import net.minecraft.server.level.TicketType;
|
||||||
import net.minecraft.server.level.TickingTracker;
|
import net.minecraft.server.level.TickingTracker;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.util.SortedArraySet;
|
import net.minecraft.util.SortedArraySet;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -285,7 +287,10 @@ abstract class DistanceManagerMixin implements ChunkSystemDistanceManager {
|
|||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public void updateSimulationDistance(final int simulationDistance) {
|
public void updateSimulationDistance(final int simulationDistance) {
|
||||||
((ChunkSystemServerLevel)this.moonrise$getChunkMap().level).moonrise$getPlayerChunkLoader().setTickDistance(simulationDistance);
|
// note: vanilla does not clamp to 0, but we do simply because we need a min of 0
|
||||||
|
final int clamped = Mth.clamp(simulationDistance, 0, MoonriseConstants.MAX_VIEW_DISTANCE);
|
||||||
|
|
||||||
|
((ChunkSystemServerLevel)this.moonrise$getChunkMap().level).moonrise$getPlayerChunkLoader().setTickDistance(clamped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -43,4 +43,17 @@ abstract class PlayerListMixin {
|
|||||||
)
|
)
|
||||||
private void doNotAdjustVD(final PlayerList instance, final Packet<?> packet) {}
|
private void doNotAdjustVD(final PlayerList instance, final Packet<?> packet) {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @reason The RegionizedPlayerChunkLoader will handle the SD packet
|
||||||
|
* @author Spottedleaf
|
||||||
|
*/
|
||||||
|
@Redirect(
|
||||||
|
method = "setSimulationDistance",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/server/players/PlayerList;broadcastAll(Lnet/minecraft/network/protocol/Packet;)V"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void doNotAdjustSD(final PlayerList instance, final Packet<?> packet) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,13 @@ abstract class ServerChunkCacheMixin extends ChunkSource implements ChunkSystemS
|
|||||||
completable::complete
|
completable::complete
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!completable.isDone() && chunkTaskScheduler.hasShutdown()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Chunk system has shut down, cannot process chunk requests in world '" + ca.spottedleaf.moonrise.common.util.WorldUtil.getWorldName(this.level) + "' at "
|
||||||
|
+ "(" + chunkX + "," + chunkZ + ") status: " + toStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) {
|
if (TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) {
|
||||||
ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ);
|
ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ);
|
||||||
this.mainThreadProcessor.managedBlock(completable::isDone);
|
this.mainThreadProcessor.managedBlock(completable::isDone);
|
||||||
@@ -315,6 +322,22 @@ abstract class ServerChunkCacheMixin extends ChunkSource implements ChunkSystemS
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @reason We need to use {@link ChunkHolder#getChunkToSend()} as the new chunk system will not bring every chunk
|
||||||
|
* sent to players up to block ticking.
|
||||||
|
* @author Spottedleaf
|
||||||
|
*/
|
||||||
|
@Redirect(
|
||||||
|
method = "broadcastChangedChunks",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/server/level/ChunkHolder;getTickingChunk()Lnet/minecraft/world/level/chunk/LevelChunk;")
|
||||||
|
)
|
||||||
|
private LevelChunk redirectTickingChunk(final ChunkHolder instance) {
|
||||||
|
return instance.getChunkToSend();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @reason Perform mid-tick chunk task processing during chunk tick
|
* @reason Perform mid-tick chunk task processing during chunk tick
|
||||||
* @author Spottedleaf
|
* @author Spottedleaf
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package ca.spottedleaf.moonrise.mixin.chunk_tick_iteration;
|
|||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||||
import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
||||||
import ca.spottedleaf.moonrise.common.util.SimpleRandom;
|
import ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk;
|
||||||
@@ -39,7 +39,7 @@ abstract class ServerChunkCacheMixin extends ChunkSource {
|
|||||||
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private final SimpleRandom shuffleRandom = new SimpleRandom(0L);
|
private final SimpleThreadUnsafeRandom shuffleRandom = new SimpleThreadUnsafeRandom(0L);
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private boolean isChunkNearPlayer(final ChunkMap chunkMap, final ChunkPos chunkPos, final LevelChunk levelChunk) {
|
private boolean isChunkNearPlayer(final ChunkMap chunkMap, final ChunkPos chunkPos, final LevelChunk levelChunk) {
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape;
|
|||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import it.unimi.dsi.fastutil.HashCommon;
|
import it.unimi.dsi.fastutil.HashCommon;
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateHolder;
|
import net.minecraft.world.level.block.state.StateHolder;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -32,7 +28,7 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
|
|||||||
protected BlockBehaviour.BlockStateBase.Cache cache;
|
protected BlockBehaviour.BlockStateBase.Cache cache;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract VoxelShape getCollisionShape(BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext);
|
public abstract boolean isAir();
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public VoxelShape[] occlusionShapesByFace;
|
public VoxelShape[] occlusionShapesByFace;
|
||||||
@@ -99,10 +95,9 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
|
|||||||
private void initCollisionState(final CallbackInfo ci) {
|
private void initCollisionState(final CallbackInfo ci) {
|
||||||
if (this.cache != null) {
|
if (this.cache != null) {
|
||||||
final VoxelShape collisionShape = this.cache.collisionShape;
|
final VoxelShape collisionShape = this.cache.collisionShape;
|
||||||
try {
|
if (this.isAir()) {
|
||||||
this.constantCollisionShape = this.getCollisionShape(null, null, null);
|
this.constantCollisionShape = Shapes.empty();
|
||||||
} catch (final Throwable throwable) {
|
} else {
|
||||||
// :(
|
|
||||||
this.constantCollisionShape = null;
|
this.constantCollisionShape = null;
|
||||||
}
|
}
|
||||||
this.occludesFullBlock = ((CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock();
|
this.occludesFullBlock = ((CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock();
|
||||||
|
|||||||
@@ -378,19 +378,19 @@ abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
|||||||
case X: {
|
case X: {
|
||||||
final double[] values = this.rootCoordinatesX;
|
final double[] values = this.rootCoordinatesX;
|
||||||
return CollisionUtil.findFloor(
|
return CollisionUtil.findFloor(
|
||||||
values, value - this.offsetX, 0, values.length - 1
|
values, this.offsetX, value, 0, values.length - 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case Y: {
|
case Y: {
|
||||||
final double[] values = this.rootCoordinatesY;
|
final double[] values = this.rootCoordinatesY;
|
||||||
return CollisionUtil.findFloor(
|
return CollisionUtil.findFloor(
|
||||||
values, value - this.offsetY, 0, values.length - 1
|
values, this.offsetY, value, 0, values.length - 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case Z: {
|
case Z: {
|
||||||
final double[] values = this.rootCoordinatesZ;
|
final double[] values = this.rootCoordinatesZ;
|
||||||
return CollisionUtil.findFloor(
|
return CollisionUtil.findFloor(
|
||||||
values, value - this.offsetZ, 0, values.length - 1
|
values, this.offsetZ, value, 0, values.length - 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -411,7 +411,7 @@ abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
|||||||
|
|
||||||
// see findIndex
|
// see findIndex
|
||||||
final int index = CollisionUtil.findFloor(
|
final int index = CollisionUtil.findFloor(
|
||||||
coords, (positiveDir ? (1.0 - CollisionUtil.COLLISION_EPSILON) : (0.0 + CollisionUtil.COLLISION_EPSILON)) - offset,
|
coords, offset, (positiveDir ? (1.0 - CollisionUtil.COLLISION_EPSILON) : (0.0 + CollisionUtil.COLLISION_EPSILON)),
|
||||||
0, coords.length - 1
|
0, coords.length - 1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ abstract class TrackedEntityMixin implements EntityTrackerTrackedEntity {
|
|||||||
@Overwrite
|
@Overwrite
|
||||||
public int getEffectiveRange() {
|
public int getEffectiveRange() {
|
||||||
final Entity entity = this.entity;
|
final Entity entity = this.entity;
|
||||||
int range = PlatformHooks.get().modifyEntityTrackingRange(entity, this.range);
|
int range = this.range;
|
||||||
|
|
||||||
if (entity.getPassengers() == ImmutableList.<Entity>of()) {
|
if (entity.getPassengers() == ImmutableList.<Entity>of()) {
|
||||||
return this.scaledRange(range);
|
return this.scaledRange(range);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ca.spottedleaf.moonrise.mixin.loading_screen;
|
package ca.spottedleaf.moonrise.mixin.loading_screen;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.ConfigHolder;
|
||||||
import net.minecraft.client.multiplayer.LevelLoadStatusManager;
|
import net.minecraft.client.multiplayer.LevelLoadStatusManager;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -25,6 +26,9 @@ abstract class LevelLoadStatusManagerMixin {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void immediatelyClose(final CallbackInfo ci) {
|
private void immediatelyClose(final CallbackInfo ci) {
|
||||||
|
if (!ConfigHolder.getConfig().misc.immediatelyCloseLoadingScreen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.status == LevelLoadStatusManager.Status.WAITING_FOR_SERVER) {
|
if (this.status == LevelLoadStatusManager.Status.WAITING_FOR_SERVER) {
|
||||||
this.status = LevelLoadStatusManager.Status.LEVEL_READY;
|
this.status = LevelLoadStatusManager.Status.LEVEL_READY;
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ abstract class AcquirePoiMixin {
|
|||||||
*/
|
*/
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = {
|
method = {
|
||||||
"method_46885",
|
"lambda$create$8",
|
||||||
"*(ZLorg/apache/commons/lang3/mutable/MutableLong;Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;Ljava/util/function/Predicate;Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;Ljava/util/Optional;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/PathfinderMob;J)Z"
|
"method_46885"
|
||||||
},
|
},
|
||||||
at = @At(
|
at = @At(
|
||||||
target = "Lnet/minecraft/world/entity/ai/village/poi/PoiManager;findAllClosestFirstWithType(Ljava/util/function/Predicate;Ljava/util/function/Predicate;Lnet/minecraft/core/BlockPos;ILnet/minecraft/world/entity/ai/village/poi/PoiManager$Occupancy;)Ljava/util/stream/Stream;",
|
target = "Lnet/minecraft/world/entity/ai/village/poi/PoiManager;findAllClosestFirstWithType(Ljava/util/function/Predicate;Ljava/util/function/Predicate;Lnet/minecraft/core/BlockPos;ILnet/minecraft/world/entity/ai/village/poi/PoiManager$Occupancy;)Ljava/util/stream/Stream;",
|
||||||
@@ -33,9 +33,9 @@ abstract class AcquirePoiMixin {
|
|||||||
ordinal = 0
|
ordinal = 0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private static Stream<Pair<Holder<PoiType>, BlockPos>> aaa(PoiManager poiManager, Predicate<Holder<PoiType>> predicate,
|
private static Stream<Pair<Holder<PoiType>, BlockPos>> useLimitedSearch(PoiManager poiManager, Predicate<Holder<PoiType>> predicate,
|
||||||
Predicate<BlockPos> predicate2, BlockPos blockPos, int i,
|
Predicate<BlockPos> predicate2, BlockPos blockPos, int i,
|
||||||
PoiManager.Occupancy occup) {
|
PoiManager.Occupancy occup) {
|
||||||
final List<Pair<Holder<PoiType>, BlockPos>> ret = new ArrayList<>();
|
final List<Pair<Holder<PoiType>, BlockPos>> ret = new ArrayList<>();
|
||||||
|
|
||||||
PoiAccess.findNearestPoiPositions(
|
PoiAccess.findNearestPoiPositions(
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package ca.spottedleaf.moonrise.mixin.random;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
abstract class EntityMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @reason Changes Entity#random to use ThreadUnsafeRandom, skipping the thread checks and CAS logic
|
||||||
|
* @author Spottedleadf
|
||||||
|
*/
|
||||||
|
@Redirect(
|
||||||
|
method = "<init>",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private RandomSource redirectEntityRandom() {
|
||||||
|
return new ThreadUnsafeRandom(RandomSupport.generateUniqueSeed());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package ca.spottedleaf.moonrise.mixin.random;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(Level.class)
|
||||||
|
abstract class LevelMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @reason Changes Level#random to use ThreadUnsafeRandom, skipping the thread checks and CAS logic
|
||||||
|
* @author Spottedleadf
|
||||||
|
*/
|
||||||
|
@Redirect(
|
||||||
|
method = "<init>",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private RandomSource redirectLevelRandom() {
|
||||||
|
return new ThreadUnsafeRandom(RandomSupport.generateUniqueSeed());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package ca.spottedleaf.moonrise.mixin.random_ticking;
|
|||||||
|
|
||||||
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||||
import ca.spottedleaf.moonrise.common.list.ShortList;
|
import ca.spottedleaf.moonrise.common.list.ShortList;
|
||||||
import ca.spottedleaf.moonrise.common.util.SimpleRandom;
|
import ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom;
|
||||||
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||||
import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection;
|
import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection;
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
@@ -20,6 +20,7 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
|||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import net.minecraft.world.level.storage.WritableLevelData;
|
import net.minecraft.world.level.storage.WritableLevelData;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -38,7 +39,7 @@ abstract class ServerLevelMixin extends Level implements WorldGenLevel {
|
|||||||
private static final LevelChunkSection[] EMPTY_SECTION_ARRAY = new LevelChunkSection[0];
|
private static final LevelChunkSection[] EMPTY_SECTION_ARRAY = new LevelChunkSection[0];
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private final SimpleRandom simpleRandom = new SimpleRandom(0L);
|
private final SimpleThreadUnsafeRandom simpleRandom = new SimpleThreadUnsafeRandom(RandomSupport.generateUniqueSeed());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @reason Use faster random
|
* @reason Use faster random
|
||||||
@@ -72,7 +73,7 @@ abstract class ServerLevelMixin extends Level implements WorldGenLevel {
|
|||||||
@Local(ordinal = 0, argsOnly = true) final int tickSpeed) {
|
@Local(ordinal = 0, argsOnly = true) final int tickSpeed) {
|
||||||
final LevelChunkSection[] sections = chunk.getSections();
|
final LevelChunkSection[] sections = chunk.getSections();
|
||||||
final int minSection = WorldUtil.getMinSection((ServerLevel)(Object)this);
|
final int minSection = WorldUtil.getMinSection((ServerLevel)(Object)this);
|
||||||
final SimpleRandom simpleRandom = this.simpleRandom;
|
final SimpleThreadUnsafeRandom simpleRandom = this.simpleRandom;
|
||||||
final boolean doubleTickFluids = !PlatformHooks.get().configFixMC224294();
|
final boolean doubleTickFluids = !PlatformHooks.get().configFixMC224294();
|
||||||
|
|
||||||
final ChunkPos cpos = chunk.getPos();
|
final ChunkPos cpos = chunk.getPos();
|
||||||
|
|||||||
@@ -1214,15 +1214,8 @@ public final class MoonriseRegionFileIO {
|
|||||||
try {
|
try {
|
||||||
writeData = this.regionDataController.startWrite(this.chunkX, this.chunkZ, write);
|
writeData = this.regionDataController.startWrite(this.chunkX, this.chunkZ, write);
|
||||||
} catch (final Throwable thr) {
|
} catch (final Throwable thr) {
|
||||||
// TODO implement this?
|
failedWrite = thr instanceof IOException;
|
||||||
/*if (thr instanceof RegionFileStorage.RegionFileSizeException) {
|
LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr);
|
||||||
final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024);
|
|
||||||
LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk.");
|
|
||||||
} else */
|
|
||||||
{
|
|
||||||
failedWrite = thr instanceof IOException;
|
|
||||||
LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeData == null) {
|
if (writeData == null) {
|
||||||
|
|||||||
@@ -291,21 +291,12 @@ public final class ChunkEntitySlices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
||||||
this.allEntities.getEntitiesWithEnderDragonParts(except, box, into, predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
|
||||||
this.allEntities.getEntities(except, box, into, predicate);
|
this.allEntities.getEntities(except, box, into, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
public boolean getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
||||||
final int maxCount) {
|
final int maxCount) {
|
||||||
return this.allEntities.getEntitiesWithEnderDragonPartsLimited(except, box, into, predicate, maxCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
|
||||||
final int maxCount) {
|
|
||||||
return this.allEntities.getEntitiesLimited(except, box, into, predicate, maxCount);
|
return this.allEntities.getEntitiesLimited(except, box, into, predicate, maxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +310,7 @@ public final class ChunkEntitySlices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entity> boolean getEntities(final EntityType<?> type, final AABB box, final List<? super T> into,
|
public <T extends Entity> boolean getEntities(final EntityType<?> type, final AABB box, final List<? super T> into,
|
||||||
final Predicate<? super T> predicate, final int maxCount) {
|
final Predicate<? super T> predicate, final int maxCount) {
|
||||||
final EntityCollectionBySection byType = this.entitiesByType.get(type);
|
final EntityCollectionBySection byType = this.entitiesByType.get(type);
|
||||||
|
|
||||||
if (byType != null) {
|
if (byType != null) {
|
||||||
@@ -356,21 +347,21 @@ public final class ChunkEntitySlices {
|
|||||||
final Predicate<? super T> predicate) {
|
final Predicate<? super T> predicate) {
|
||||||
EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
|
EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
|
||||||
if (collection != null) {
|
if (collection != null) {
|
||||||
collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List)into, (Predicate)predicate);
|
collection.getEntities(except, box, (List)into, (Predicate)predicate);
|
||||||
} else {
|
} else {
|
||||||
this.entitiesByClass.put(clazz, collection = this.initClass(clazz));
|
this.entitiesByClass.put(clazz, collection = this.initClass(clazz));
|
||||||
collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List)into, (Predicate)predicate);
|
collection.getEntities(except, box, (List)into, (Predicate)predicate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entity> boolean getEntities(final Class<? extends T> clazz, final Entity except, final AABB box, final List<? super T> into,
|
public <T extends Entity> boolean getEntities(final Class<? extends T> clazz, final Entity except, final AABB box, final List<? super T> into,
|
||||||
final Predicate<? super T> predicate, final int maxCount) {
|
final Predicate<? super T> predicate, final int maxCount) {
|
||||||
EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
|
EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
|
||||||
if (collection != null) {
|
if (collection != null) {
|
||||||
return collection.getEntitiesWithEnderDragonPartsLimited(except, clazz, box, (List)into, (Predicate)predicate, maxCount);
|
return collection.getEntitiesLimited(except, box, (List)into, (Predicate)predicate, maxCount);
|
||||||
} else {
|
} else {
|
||||||
this.entitiesByClass.put(clazz, collection = this.initClass(clazz));
|
this.entitiesByClass.put(clazz, collection = this.initClass(clazz));
|
||||||
return collection.getEntitiesWithEnderDragonPartsLimited(except, clazz, box, (List)into, (Predicate)predicate, maxCount);
|
return collection.getEntitiesLimited(except, box, (List)into, (Predicate)predicate, maxCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,225 +565,5 @@ public final class ChunkEntitySlices {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getEntitiesWithEnderDragonParts(final Entity except, final AABB box, final List<Entity> into,
|
|
||||||
final Predicate<? super Entity> predicate) {
|
|
||||||
if (this.count == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minSection = this.slices.minSection;
|
|
||||||
final int maxSection = this.slices.maxSection;
|
|
||||||
|
|
||||||
final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection);
|
|
||||||
final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection);
|
|
||||||
|
|
||||||
final BasicEntityList<Entity>[] entitiesBySection = this.entitiesBySection;
|
|
||||||
|
|
||||||
for (int section = min; section <= max; ++section) {
|
|
||||||
final BasicEntityList<Entity> list = entitiesBySection[section - minSection];
|
|
||||||
|
|
||||||
if (list == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Entity[] storage = list.storage;
|
|
||||||
|
|
||||||
for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) {
|
|
||||||
final Entity entity = storage[i];
|
|
||||||
|
|
||||||
if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate == null || predicate.test(entity)) {
|
|
||||||
into.add(entity);
|
|
||||||
} // else: continue to test the ender dragon parts
|
|
||||||
|
|
||||||
if (entity instanceof EnderDragon) {
|
|
||||||
for (final EnderDragonPart part : ((EnderDragon)entity).getSubEntities()) {
|
|
||||||
if (part == except || !part.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate != null && !predicate.test(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
into.add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getEntitiesWithEnderDragonPartsLimited(final Entity except, final AABB box, final List<Entity> into,
|
|
||||||
final Predicate<? super Entity> predicate, final int maxCount) {
|
|
||||||
if (this.count == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minSection = this.slices.minSection;
|
|
||||||
final int maxSection = this.slices.maxSection;
|
|
||||||
|
|
||||||
final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection);
|
|
||||||
final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection);
|
|
||||||
|
|
||||||
final BasicEntityList<Entity>[] entitiesBySection = this.entitiesBySection;
|
|
||||||
|
|
||||||
for (int section = min; section <= max; ++section) {
|
|
||||||
final BasicEntityList<Entity> list = entitiesBySection[section - minSection];
|
|
||||||
|
|
||||||
if (list == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Entity[] storage = list.storage;
|
|
||||||
|
|
||||||
for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) {
|
|
||||||
final Entity entity = storage[i];
|
|
||||||
|
|
||||||
if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate == null || predicate.test(entity)) {
|
|
||||||
into.add(entity);
|
|
||||||
if (into.size() >= maxCount) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // else: continue to test the ender dragon parts
|
|
||||||
|
|
||||||
if (entity instanceof EnderDragon) {
|
|
||||||
for (final EnderDragonPart part : ((EnderDragon)entity).getSubEntities()) {
|
|
||||||
if (part == except || !part.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate != null && !predicate.test(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
into.add(part);
|
|
||||||
if (into.size() >= maxCount) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getEntitiesWithEnderDragonParts(final Entity except, final Class<?> clazz, final AABB box, final List<Entity> into,
|
|
||||||
final Predicate<? super Entity> predicate) {
|
|
||||||
if (this.count == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minSection = this.slices.minSection;
|
|
||||||
final int maxSection = this.slices.maxSection;
|
|
||||||
|
|
||||||
final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection);
|
|
||||||
final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection);
|
|
||||||
|
|
||||||
final BasicEntityList<Entity>[] entitiesBySection = this.entitiesBySection;
|
|
||||||
|
|
||||||
for (int section = min; section <= max; ++section) {
|
|
||||||
final BasicEntityList<Entity> list = entitiesBySection[section - minSection];
|
|
||||||
|
|
||||||
if (list == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Entity[] storage = list.storage;
|
|
||||||
|
|
||||||
for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) {
|
|
||||||
final Entity entity = storage[i];
|
|
||||||
|
|
||||||
if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate == null || predicate.test(entity)) {
|
|
||||||
into.add(entity);
|
|
||||||
} // else: continue to test the ender dragon parts
|
|
||||||
|
|
||||||
if (entity instanceof EnderDragon) {
|
|
||||||
for (final EnderDragonPart part : ((EnderDragon)entity).getSubEntities()) {
|
|
||||||
if (part == except || !part.getBoundingBox().intersects(box) || !clazz.isInstance(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate != null && !predicate.test(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
into.add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getEntitiesWithEnderDragonPartsLimited(final Entity except, final Class<?> clazz, final AABB box, final List<Entity> into,
|
|
||||||
final Predicate<? super Entity> predicate, final int maxCount) {
|
|
||||||
if (this.count == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minSection = this.slices.minSection;
|
|
||||||
final int maxSection = this.slices.maxSection;
|
|
||||||
|
|
||||||
final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection);
|
|
||||||
final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection);
|
|
||||||
|
|
||||||
final BasicEntityList<Entity>[] entitiesBySection = this.entitiesBySection;
|
|
||||||
|
|
||||||
for (int section = min; section <= max; ++section) {
|
|
||||||
final BasicEntityList<Entity> list = entitiesBySection[section - minSection];
|
|
||||||
|
|
||||||
if (list == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Entity[] storage = list.storage;
|
|
||||||
|
|
||||||
for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) {
|
|
||||||
final Entity entity = storage[i];
|
|
||||||
|
|
||||||
if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate == null || predicate.test(entity)) {
|
|
||||||
into.add(entity);
|
|
||||||
if (into.size() >= maxCount) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // else: continue to test the ender dragon parts
|
|
||||||
|
|
||||||
if (entity instanceof EnderDragon) {
|
|
||||||
for (final EnderDragonPart part : ((EnderDragon)entity).getSubEntities()) {
|
|
||||||
if (part == except || !part.getBoundingBox().intersects(box) || !clazz.isInstance(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (predicate != null && !predicate.test(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
into.add(part);
|
|
||||||
if (into.size() >= maxCount) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|||||||
@Override
|
@Override
|
||||||
public void get(final AABB box, final Consumer<Entity> action) {
|
public void get(final AABB box, final Consumer<Entity> action) {
|
||||||
List<Entity> entities = new ArrayList<>();
|
List<Entity> entities = new ArrayList<>();
|
||||||
this.getEntitiesWithoutDragonParts(null, box, entities, null);
|
this.getEntities((Entity)null, box, entities, null);
|
||||||
for (int i = 0, len = entities.size(); i < len; ++i) {
|
for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||||
action.accept(entities.get(i));
|
action.accept(entities.get(i));
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|||||||
@Override
|
@Override
|
||||||
public <U extends Entity> void get(final EntityTypeTest<Entity, U> filter, final AABB box, final AbortableIterationConsumer<U> action) {
|
public <U extends Entity> void get(final EntityTypeTest<Entity, U> filter, final AABB box, final AbortableIterationConsumer<U> action) {
|
||||||
List<Entity> entities = new ArrayList<>();
|
List<Entity> entities = new ArrayList<>();
|
||||||
this.getEntitiesWithoutDragonParts(null, box, entities, null);
|
this.getEntities((Entity)null, box, entities, null);
|
||||||
for (int i = 0, len = entities.size(); i < len; ++i) {
|
for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||||
final U casted = filter.tryCast(entities.get(i));
|
final U casted = filter.tryCast(entities.get(i));
|
||||||
if (casted != null && action.accept(casted).shouldAbort()) {
|
if (casted != null && action.accept(casted).shouldAbort()) {
|
||||||
@@ -560,45 +560,6 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|||||||
return slices;
|
return slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
|
||||||
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
|
||||||
final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4;
|
|
||||||
final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4;
|
|
||||||
final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4;
|
|
||||||
|
|
||||||
final int minRegionX = minChunkX >> REGION_SHIFT;
|
|
||||||
final int minRegionZ = minChunkZ >> REGION_SHIFT;
|
|
||||||
final int maxRegionX = maxChunkX >> REGION_SHIFT;
|
|
||||||
final int maxRegionZ = maxChunkZ >> REGION_SHIFT;
|
|
||||||
|
|
||||||
for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) {
|
|
||||||
final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0;
|
|
||||||
final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK;
|
|
||||||
|
|
||||||
for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) {
|
|
||||||
final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ);
|
|
||||||
|
|
||||||
if (region == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0;
|
|
||||||
final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK;
|
|
||||||
|
|
||||||
for (int currZ = minZ; currZ <= maxZ; ++currZ) {
|
|
||||||
for (int currX = minX; currX <= maxX; ++currX) {
|
|
||||||
final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT));
|
|
||||||
if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk.getEntitiesWithoutDragonParts(except, box, into, predicate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
||||||
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
||||||
final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4;
|
final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4;
|
||||||
@@ -759,48 +720,6 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|||||||
|
|
||||||
//////// Limited ////////
|
//////// Limited ////////
|
||||||
|
|
||||||
public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
|
||||||
final int maxCount) {
|
|
||||||
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
|
||||||
final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4;
|
|
||||||
final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4;
|
|
||||||
final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4;
|
|
||||||
|
|
||||||
final int minRegionX = minChunkX >> REGION_SHIFT;
|
|
||||||
final int minRegionZ = minChunkZ >> REGION_SHIFT;
|
|
||||||
final int maxRegionX = maxChunkX >> REGION_SHIFT;
|
|
||||||
final int maxRegionZ = maxChunkZ >> REGION_SHIFT;
|
|
||||||
|
|
||||||
for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) {
|
|
||||||
final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0;
|
|
||||||
final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK;
|
|
||||||
|
|
||||||
for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) {
|
|
||||||
final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ);
|
|
||||||
|
|
||||||
if (region == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0;
|
|
||||||
final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK;
|
|
||||||
|
|
||||||
for (int currZ = minZ; currZ <= maxZ; ++currZ) {
|
|
||||||
for (int currX = minX; currX <= maxX; ++currX) {
|
|
||||||
final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT));
|
|
||||||
if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunk.getEntitiesWithoutDragonParts(except, box, into, predicate, maxCount)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate,
|
||||||
final int maxCount) {
|
final int maxCount) {
|
||||||
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
final int minChunkX = (Mth.floor(box.minX) - 2) >> 4;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import ca.spottedleaf.moonrise.common.PlatformHooks;
|
|||||||
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||||
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup;
|
||||||
@@ -111,6 +110,6 @@ public final class ServerEntityLookup extends EntityLookup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) {
|
protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) {
|
||||||
return ChunkSystem.screenEntity(this.serverWorld, entity, fromDisk, event);
|
return PlatformHooks.get().screenEntity(this.serverWorld, entity, fromDisk, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import ca.spottedleaf.moonrise.common.PlatformHooks;
|
|||||||
import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter;
|
import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter;
|
||||||
import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap;
|
import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap;
|
||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
|
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
|
||||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
@@ -114,14 +115,25 @@ public final class RegionizedPlayerChunkLoader {
|
|||||||
int sendViewDistance
|
int sendViewDistance
|
||||||
) {
|
) {
|
||||||
public ViewDistances setTickViewDistance(final int distance) {
|
public ViewDistances setTickViewDistance(final int distance) {
|
||||||
|
if (distance != -1 && (distance < (0) || distance > (MoonriseConstants.MAX_VIEW_DISTANCE))) {
|
||||||
|
throw new IllegalArgumentException(Integer.toString(distance));
|
||||||
|
}
|
||||||
return new ViewDistances(distance, this.loadViewDistance, this.sendViewDistance);
|
return new ViewDistances(distance, this.loadViewDistance, this.sendViewDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewDistances setLoadViewDistance(final int distance) {
|
public ViewDistances setLoadViewDistance(final int distance) {
|
||||||
|
// note: load view distance = api view distance + 1
|
||||||
|
if (distance != -1 && (distance < (2 + 1) || distance > (MoonriseConstants.MAX_VIEW_DISTANCE + 1))) {
|
||||||
|
throw new IllegalArgumentException(Integer.toString(distance));
|
||||||
|
}
|
||||||
return new ViewDistances(this.tickViewDistance, distance, this.sendViewDistance);
|
return new ViewDistances(this.tickViewDistance, distance, this.sendViewDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewDistances setSendViewDistance(final int distance) {
|
public ViewDistances setSendViewDistance(final int distance) {
|
||||||
|
// note: send view distance <= load view distance - 1
|
||||||
|
if (distance != -1 && (distance < (0) || distance > (MoonriseConstants.MAX_VIEW_DISTANCE))) {
|
||||||
|
throw new IllegalArgumentException(Integer.toString(distance));
|
||||||
|
}
|
||||||
return new ViewDistances(this.tickViewDistance, this.loadViewDistance, distance);
|
return new ViewDistances(this.tickViewDistance, this.loadViewDistance, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,16 +167,6 @@ public final class RegionizedPlayerChunkLoader {
|
|||||||
return data.lastLoadDistance - 1;
|
return data.lastLoadDistance - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLoadViewDistance(final ServerPlayer player) {
|
|
||||||
final ServerLevel level = player.serverLevel();
|
|
||||||
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
|
|
||||||
if (data == null) {
|
|
||||||
return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPIViewDistance();
|
|
||||||
}
|
|
||||||
// view distance = load distance + 1
|
|
||||||
return data.lastLoadDistance - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getAPISendViewDistance(final ServerPlayer player) {
|
public static int getAPISendViewDistance(final ServerPlayer player) {
|
||||||
final ServerLevel level = player.serverLevel();
|
final ServerLevel level = player.serverLevel();
|
||||||
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
|
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
|
||||||
@@ -516,7 +518,7 @@ public final class RegionizedPlayerChunkLoader {
|
|||||||
final int playerLoadViewDistance, final int worldLoadViewDistance) {
|
final int playerLoadViewDistance, final int worldLoadViewDistance) {
|
||||||
return Math.min(
|
return Math.min(
|
||||||
playerTickViewDistance < 0 ? worldTickViewDistance : playerTickViewDistance,
|
playerTickViewDistance < 0 ? worldTickViewDistance : playerTickViewDistance,
|
||||||
playerLoadViewDistance < 0 ? worldLoadViewDistance : playerLoadViewDistance
|
playerLoadViewDistance < 0 ? (worldLoadViewDistance - 1) : (playerLoadViewDistance - 1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import ca.spottedleaf.moonrise.common.PlatformHooks;
|
|||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||||
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||||
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
||||||
@@ -219,6 +218,8 @@ public final class ChunkHolderManager {
|
|||||||
LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex);
|
LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.taskScheduler.setShutdown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureInAutosave(final NewChunkHolder holder) {
|
void ensureInAutosave(final NewChunkHolder holder) {
|
||||||
@@ -816,7 +817,7 @@ public final class ChunkHolderManager {
|
|||||||
private NewChunkHolder createChunkHolder(final long position) {
|
private NewChunkHolder createChunkHolder(final long position) {
|
||||||
final NewChunkHolder ret = new NewChunkHolder(this.world, CoordinateUtils.getChunkX(position), CoordinateUtils.getChunkZ(position), this.taskScheduler);
|
final NewChunkHolder ret = new NewChunkHolder(this.world, CoordinateUtils.getChunkX(position), CoordinateUtils.getChunkZ(position), this.taskScheduler);
|
||||||
|
|
||||||
ChunkSystem.onChunkHolderCreate(this.world, ret.vanillaChunkHolder);
|
PlatformHooks.get().onChunkHolderCreate(this.world, ret.vanillaChunkHolder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1024,7 +1025,7 @@ public final class ChunkHolderManager {
|
|||||||
private void removeChunkHolder(final NewChunkHolder holder) {
|
private void removeChunkHolder(final NewChunkHolder holder) {
|
||||||
holder.onUnload();
|
holder.onUnload();
|
||||||
this.autoSaveQueue.remove(holder);
|
this.autoSaveQueue.remove(holder);
|
||||||
ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder);
|
PlatformHooks.get().onChunkHolderDelete(this.world, holder.vanillaChunkHolder);
|
||||||
this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ));
|
this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -271,6 +271,16 @@ public final class ChunkTaskScheduler {
|
|||||||
return this.lockShift;
|
return this.lockShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private volatile boolean shutdown;
|
||||||
|
|
||||||
|
public boolean hasShutdown() {
|
||||||
|
return this.shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShutdown(final boolean shutdown) {
|
||||||
|
this.shutdown = shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
public ChunkTaskScheduler(final ServerLevel world) {
|
public ChunkTaskScheduler(final ServerLevel world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
// must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift
|
// must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift
|
||||||
@@ -525,6 +535,13 @@ public final class ChunkTaskScheduler {
|
|||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.hasShutdown()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Chunk system has shut down, cannot process chunk requests in world '" + ca.spottedleaf.moonrise.common.util.WorldUtil.getWorldName(this.world) + "' at "
|
||||||
|
+ "(" + chunkX + "," + chunkZ + ") status: " + status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final Long ticketId = getNextNonFullLoadId();
|
final Long ticketId = getNextNonFullLoadId();
|
||||||
final int ticketLevel = getTicketLevel(status);
|
final int ticketLevel = getTicketLevel(status);
|
||||||
this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId);
|
this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId);
|
||||||
@@ -579,7 +596,7 @@ public final class ChunkTaskScheduler {
|
|||||||
this.chunkHolderManager.processTicketUpdates();
|
this.chunkHolderManager.processTicketUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> {
|
final Consumer<ChunkAccess> loadCallback = onComplete == null && !addTicket ? null : (final ChunkAccess chunk) -> {
|
||||||
try {
|
try {
|
||||||
if (onComplete != null) {
|
if (onComplete != null) {
|
||||||
onComplete.accept(chunk);
|
onComplete.accept(chunk);
|
||||||
@@ -616,7 +633,9 @@ public final class ChunkTaskScheduler {
|
|||||||
if (!chunkHolder.upgradeGenTarget(toStatus)) {
|
if (!chunkHolder.upgradeGenTarget(toStatus)) {
|
||||||
this.schedule(chunkX, chunkZ, toStatus, chunkHolder, tasks);
|
this.schedule(chunkX, chunkZ, toStatus, chunkHolder, tasks);
|
||||||
}
|
}
|
||||||
chunkHolder.addStatusConsumer(toStatus, loadCallback);
|
if (loadCallback != null) {
|
||||||
|
chunkHolder.addStatusConsumer(toStatus, loadCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -630,7 +649,7 @@ public final class ChunkTaskScheduler {
|
|||||||
tasks.get(i).schedule();
|
tasks.get(i).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scheduled) {
|
if (loadCallback != null && !scheduled) {
|
||||||
// couldn't schedule
|
// couldn't schedule
|
||||||
try {
|
try {
|
||||||
loadCallback.accept(chunk);
|
loadCallback.accept(chunk);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import ca.spottedleaf.moonrise.common.misc.LazyRunnable;
|
|||||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||||
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||||
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
|
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
|
||||||
@@ -1270,10 +1269,10 @@ public final class NewChunkHolder {
|
|||||||
// state upgrade
|
// state upgrade
|
||||||
if (!current.isOrAfter(FullChunkStatus.FULL) && pending.isOrAfter(FullChunkStatus.FULL)) {
|
if (!current.isOrAfter(FullChunkStatus.FULL) && pending.isOrAfter(FullChunkStatus.FULL)) {
|
||||||
this.updateCurrentState(FullChunkStatus.FULL);
|
this.updateCurrentState(FullChunkStatus.FULL);
|
||||||
ChunkSystem.onChunkPreBorder(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkPreBorder(chunk, this.vanillaChunkHolder);
|
||||||
this.scheduler.chunkHolderManager.ensureInAutosave(this);
|
this.scheduler.chunkHolderManager.ensureInAutosave(this);
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.FULL);
|
this.changeEntityChunkStatus(FullChunkStatus.FULL);
|
||||||
ChunkSystem.onChunkBorder(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkBorder(chunk, this.vanillaChunkHolder);
|
||||||
this.onFullChunkLoadChange(true, changedFullStatus);
|
this.onFullChunkLoadChange(true, changedFullStatus);
|
||||||
this.completeFullStatusConsumers(FullChunkStatus.FULL, chunk);
|
this.completeFullStatusConsumers(FullChunkStatus.FULL, chunk);
|
||||||
}
|
}
|
||||||
@@ -1281,34 +1280,34 @@ public final class NewChunkHolder {
|
|||||||
if (!current.isOrAfter(FullChunkStatus.BLOCK_TICKING) && pending.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
if (!current.isOrAfter(FullChunkStatus.BLOCK_TICKING) && pending.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
||||||
this.updateCurrentState(FullChunkStatus.BLOCK_TICKING);
|
this.updateCurrentState(FullChunkStatus.BLOCK_TICKING);
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING);
|
this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING);
|
||||||
ChunkSystem.onChunkTicking(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkTicking(chunk, this.vanillaChunkHolder);
|
||||||
this.completeFullStatusConsumers(FullChunkStatus.BLOCK_TICKING, chunk);
|
this.completeFullStatusConsumers(FullChunkStatus.BLOCK_TICKING, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!current.isOrAfter(FullChunkStatus.ENTITY_TICKING) && pending.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
if (!current.isOrAfter(FullChunkStatus.ENTITY_TICKING) && pending.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||||
this.updateCurrentState(FullChunkStatus.ENTITY_TICKING);
|
this.updateCurrentState(FullChunkStatus.ENTITY_TICKING);
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.ENTITY_TICKING);
|
this.changeEntityChunkStatus(FullChunkStatus.ENTITY_TICKING);
|
||||||
ChunkSystem.onChunkEntityTicking(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkEntityTicking(chunk, this.vanillaChunkHolder);
|
||||||
this.completeFullStatusConsumers(FullChunkStatus.ENTITY_TICKING, chunk);
|
this.completeFullStatusConsumers(FullChunkStatus.ENTITY_TICKING, chunk);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (current.isOrAfter(FullChunkStatus.ENTITY_TICKING) && !pending.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
if (current.isOrAfter(FullChunkStatus.ENTITY_TICKING) && !pending.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING);
|
this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING);
|
||||||
ChunkSystem.onChunkNotEntityTicking(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkNotEntityTicking(chunk, this.vanillaChunkHolder);
|
||||||
this.updateCurrentState(FullChunkStatus.BLOCK_TICKING);
|
this.updateCurrentState(FullChunkStatus.BLOCK_TICKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.isOrAfter(FullChunkStatus.BLOCK_TICKING) && !pending.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
if (current.isOrAfter(FullChunkStatus.BLOCK_TICKING) && !pending.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.FULL);
|
this.changeEntityChunkStatus(FullChunkStatus.FULL);
|
||||||
ChunkSystem.onChunkNotTicking(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkNotTicking(chunk, this.vanillaChunkHolder);
|
||||||
this.updateCurrentState(FullChunkStatus.FULL);
|
this.updateCurrentState(FullChunkStatus.FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.isOrAfter(FullChunkStatus.FULL) && !pending.isOrAfter(FullChunkStatus.FULL)) {
|
if (current.isOrAfter(FullChunkStatus.FULL) && !pending.isOrAfter(FullChunkStatus.FULL)) {
|
||||||
this.onFullChunkLoadChange(false, changedFullStatus);
|
this.onFullChunkLoadChange(false, changedFullStatus);
|
||||||
this.changeEntityChunkStatus(FullChunkStatus.INACCESSIBLE);
|
this.changeEntityChunkStatus(FullChunkStatus.INACCESSIBLE);
|
||||||
ChunkSystem.onChunkNotBorder(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkNotBorder(chunk, this.vanillaChunkHolder);
|
||||||
ChunkSystem.onChunkPostNotBorder(chunk, this.vanillaChunkHolder);
|
PlatformHooks.get().onChunkPostNotBorder(chunk, this.vanillaChunkHolder);
|
||||||
this.updateCurrentState(FullChunkStatus.INACCESSIBLE);
|
this.updateCurrentState(FullChunkStatus.INACCESSIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,11 +166,11 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
// startIndex and endIndex inclusive
|
// startIndex and endIndex inclusive
|
||||||
// assumes indices are in range of array
|
// assumes indices are in range of array
|
||||||
public static int findFloor(final double[] values, final double value, int startIndex, int endIndex) {
|
public static int findFloor(final double[] values, final double offset, final double value, int startIndex, int endIndex) {
|
||||||
Objects.checkFromToIndex(startIndex, endIndex + 1, values.length);
|
Objects.checkFromToIndex(startIndex, endIndex + 1, values.length);
|
||||||
do {
|
do {
|
||||||
final int middle = (startIndex + endIndex) >>> 1;
|
final int middle = (startIndex + endIndex) >>> 1;
|
||||||
final double middleVal = values[middle];
|
final double middleVal = (values[middle] + offset);
|
||||||
|
|
||||||
if (value < middleVal) {
|
if (value < middleVal) {
|
||||||
endIndex = middle - 1;
|
endIndex = middle - 1;
|
||||||
@@ -419,8 +419,6 @@ public final class CollisionUtil {
|
|||||||
// an AABB(coords_x[x], coords_y[y], coords_z[z], coords_x[x + 1], coords_y[y + 1], coords_z[z + 1])
|
// an AABB(coords_x[x], coords_y[y], coords_z[z], coords_x[x + 1], coords_y[y + 1], coords_z[z + 1])
|
||||||
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
||||||
|
|
||||||
// note: we should be offsetting coords, but we can also just subtract from source as well - which is
|
|
||||||
// a win in terms of ops / simplicity (see findFloor, allows us to not modify coords for that)
|
|
||||||
// note: for intersection, one we find the floor of the min we can use that as the start index
|
// note: for intersection, one we find the floor of the min we can use that as the start index
|
||||||
// for the next check as source max >= source min
|
// for the next check as source max >= source min
|
||||||
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
||||||
@@ -429,7 +427,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_x = Math.max(
|
final int floor_min_x = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_x, (aabb.minX - off_x) + COLLISION_EPSILON, 0, size_x)
|
findFloor(coords_x, off_x, aabb.minX + COLLISION_EPSILON, 0, size_x)
|
||||||
);
|
);
|
||||||
if (floor_min_x >= size_x) {
|
if (floor_min_x >= size_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -438,7 +436,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_x = Math.min(
|
final int ceil_max_x = Math.min(
|
||||||
size_x,
|
size_x,
|
||||||
findFloor(coords_x, (aabb.maxX - off_x) - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
findFloor(coords_x, off_x, aabb.maxX - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_x >= ceil_max_x) {
|
if (floor_min_x >= ceil_max_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -447,7 +445,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_y = Math.max(
|
final int floor_min_y = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_y, (aabb.minY - off_y) + COLLISION_EPSILON, 0, size_y)
|
findFloor(coords_y, off_y, aabb.minY + COLLISION_EPSILON, 0, size_y)
|
||||||
);
|
);
|
||||||
if (floor_min_y >= size_y) {
|
if (floor_min_y >= size_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -456,7 +454,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_y = Math.min(
|
final int ceil_max_y = Math.min(
|
||||||
size_y,
|
size_y,
|
||||||
findFloor(coords_y, (aabb.maxY - off_y) - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
findFloor(coords_y, off_y, aabb.maxY - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_y >= ceil_max_y) {
|
if (floor_min_y >= ceil_max_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -465,7 +463,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_z = Math.max(
|
final int floor_min_z = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_z, (aabb.minZ - off_z) + COLLISION_EPSILON, 0, size_z)
|
findFloor(coords_z, off_z, aabb.minZ + COLLISION_EPSILON, 0, size_z)
|
||||||
);
|
);
|
||||||
if (floor_min_z >= size_z) {
|
if (floor_min_z >= size_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -474,7 +472,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_z = Math.min(
|
final int ceil_max_z = Math.min(
|
||||||
size_z,
|
size_z,
|
||||||
findFloor(coords_z, (aabb.maxZ - off_z) - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
findFloor(coords_z, off_z, aabb.maxZ - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_z >= ceil_max_z) {
|
if (floor_min_z >= ceil_max_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -530,8 +528,6 @@ public final class CollisionUtil {
|
|||||||
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
||||||
|
|
||||||
|
|
||||||
// note: we should be offsetting coords, but we can also just subtract from source as well - which is
|
|
||||||
// a win in terms of ops / simplicity (see findFloor, allows us to not modify coords for that)
|
|
||||||
// note: for intersection, one we find the floor of the min we can use that as the start index
|
// note: for intersection, one we find the floor of the min we can use that as the start index
|
||||||
// for the next check as source max >= source min
|
// for the next check as source max >= source min
|
||||||
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
||||||
@@ -540,7 +536,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_y = Math.max(
|
final int floor_min_y = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_y, (source.minY - off_y) + COLLISION_EPSILON, 0, size_y)
|
findFloor(coords_y, off_y, source.minY + COLLISION_EPSILON, 0, size_y)
|
||||||
);
|
);
|
||||||
if (floor_min_y >= size_y) {
|
if (floor_min_y >= size_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -549,7 +545,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_y = Math.min(
|
final int ceil_max_y = Math.min(
|
||||||
size_y,
|
size_y,
|
||||||
findFloor(coords_y, (source.maxY - off_y) - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
findFloor(coords_y, off_y, source.maxY - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_y >= ceil_max_y) {
|
if (floor_min_y >= ceil_max_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -558,7 +554,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_z = Math.max(
|
final int floor_min_z = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_z, (source.minZ - off_z) + COLLISION_EPSILON, 0, size_z)
|
findFloor(coords_z, off_z, source.minZ + COLLISION_EPSILON, 0, size_z)
|
||||||
);
|
);
|
||||||
if (floor_min_z >= size_z) {
|
if (floor_min_z >= size_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -567,7 +563,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_z = Math.min(
|
final int ceil_max_z = Math.min(
|
||||||
size_z,
|
size_z,
|
||||||
findFloor(coords_z, (source.maxZ - off_z) - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
findFloor(coords_z, off_z, source.maxZ - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_z >= ceil_max_z) {
|
if (floor_min_z >= ceil_max_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -579,9 +575,9 @@ public final class CollisionUtil {
|
|||||||
final long[] bitset = cached_shape_data.voxelSet();
|
final long[] bitset = cached_shape_data.voxelSet();
|
||||||
|
|
||||||
if (source_move > 0.0) {
|
if (source_move > 0.0) {
|
||||||
final double source_max = source.maxX - off_x;
|
final double source_max = source.maxX;
|
||||||
final int ceil_max_x = findFloor(
|
final int ceil_max_x = findFloor(
|
||||||
coords_x, source_max - COLLISION_EPSILON, 0, size_x
|
coords_x, off_x, source_max - COLLISION_EPSILON, 0, size_x
|
||||||
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -590,7 +586,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_x = ceil_max_x; curr_x < size_x; ++curr_x) {
|
for (int curr_x = ceil_max_x; curr_x < size_x; ++curr_x) {
|
||||||
double max_dist = coords_x[curr_x] - source_max;
|
double max_dist = (coords_x[curr_x] + off_x) - source_max;
|
||||||
if (max_dist >= source_move) {
|
if (max_dist >= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
||||||
@@ -617,9 +613,9 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
return source_move;
|
return source_move;
|
||||||
} else {
|
} else {
|
||||||
final double source_min = source.minX - off_x;
|
final double source_min = source.minX;
|
||||||
final int floor_min_x = findFloor(
|
final int floor_min_x = findFloor(
|
||||||
coords_x, source_min + COLLISION_EPSILON, 0, size_x
|
coords_x, off_x, source_min + COLLISION_EPSILON, 0, size_x
|
||||||
);
|
);
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -631,7 +627,7 @@ public final class CollisionUtil {
|
|||||||
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_x = floor_min_x - 1; curr_x >= 0; --curr_x) {
|
for (int curr_x = floor_min_x - 1; curr_x >= 0; --curr_x) {
|
||||||
double max_dist = coords_x[curr_x + 1] - source_min;
|
double max_dist = (coords_x[curr_x + 1] + off_x) - source_min;
|
||||||
if (max_dist <= source_move) {
|
if (max_dist <= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
||||||
@@ -688,8 +684,6 @@ public final class CollisionUtil {
|
|||||||
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
||||||
|
|
||||||
|
|
||||||
// note: we should be offsetting coords, but we can also just subtract from source as well - which is
|
|
||||||
// a win in terms of ops / simplicity (see findFloor, allows us to not modify coords for that)
|
|
||||||
// note: for intersection, one we find the floor of the min we can use that as the start index
|
// note: for intersection, one we find the floor of the min we can use that as the start index
|
||||||
// for the next check as source max >= source min
|
// for the next check as source max >= source min
|
||||||
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
||||||
@@ -698,7 +692,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_x = Math.max(
|
final int floor_min_x = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_x, (source.minX - off_x) + COLLISION_EPSILON, 0, size_x)
|
findFloor(coords_x, off_x, source.minX + COLLISION_EPSILON, 0, size_x)
|
||||||
);
|
);
|
||||||
if (floor_min_x >= size_x) {
|
if (floor_min_x >= size_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -707,7 +701,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_x = Math.min(
|
final int ceil_max_x = Math.min(
|
||||||
size_x,
|
size_x,
|
||||||
findFloor(coords_x, (source.maxX - off_x) - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
findFloor(coords_x, off_x, source.maxX - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_x >= ceil_max_x) {
|
if (floor_min_x >= ceil_max_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -716,7 +710,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_z = Math.max(
|
final int floor_min_z = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_z, (source.minZ - off_z) + COLLISION_EPSILON, 0, size_z)
|
findFloor(coords_z, off_z, source.minZ + COLLISION_EPSILON, 0, size_z)
|
||||||
);
|
);
|
||||||
if (floor_min_z >= size_z) {
|
if (floor_min_z >= size_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -725,7 +719,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_z = Math.min(
|
final int ceil_max_z = Math.min(
|
||||||
size_z,
|
size_z,
|
||||||
findFloor(coords_z, (source.maxZ - off_z) - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
findFloor(coords_z, off_z, source.maxZ - COLLISION_EPSILON, floor_min_z, size_z) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_z >= ceil_max_z) {
|
if (floor_min_z >= ceil_max_z) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -737,9 +731,9 @@ public final class CollisionUtil {
|
|||||||
final long[] bitset = cached_shape_data.voxelSet();
|
final long[] bitset = cached_shape_data.voxelSet();
|
||||||
|
|
||||||
if (source_move > 0.0) {
|
if (source_move > 0.0) {
|
||||||
final double source_max = source.maxY - off_y;
|
final double source_max = source.maxY;
|
||||||
final int ceil_max_y = findFloor(
|
final int ceil_max_y = findFloor(
|
||||||
coords_y, source_max - COLLISION_EPSILON, 0, size_y
|
coords_y, off_y, source_max - COLLISION_EPSILON, 0, size_y
|
||||||
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -748,7 +742,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_y = ceil_max_y; curr_y < size_y; ++curr_y) {
|
for (int curr_y = ceil_max_y; curr_y < size_y; ++curr_y) {
|
||||||
double max_dist = coords_y[curr_y] - source_max;
|
double max_dist = (coords_y[curr_y] + off_y) - source_max;
|
||||||
if (max_dist >= source_move) {
|
if (max_dist >= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
||||||
@@ -775,9 +769,9 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
return source_move;
|
return source_move;
|
||||||
} else {
|
} else {
|
||||||
final double source_min = source.minY - off_y;
|
final double source_min = source.minY;
|
||||||
final int floor_min_y = findFloor(
|
final int floor_min_y = findFloor(
|
||||||
coords_y, source_min + COLLISION_EPSILON, 0, size_y
|
coords_y, off_y, source_min + COLLISION_EPSILON, 0, size_y
|
||||||
);
|
);
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -789,7 +783,7 @@ public final class CollisionUtil {
|
|||||||
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_y = floor_min_y - 1; curr_y >= 0; --curr_y) {
|
for (int curr_y = floor_min_y - 1; curr_y >= 0; --curr_y) {
|
||||||
double max_dist = coords_y[curr_y + 1] - source_min;
|
double max_dist = (coords_y[curr_y + 1] + off_y) - source_min;
|
||||||
if (max_dist <= source_move) {
|
if (max_dist <= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
||||||
@@ -846,8 +840,6 @@ public final class CollisionUtil {
|
|||||||
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
// is collidable. this is the fundamental principle of operation for the voxel collision operation
|
||||||
|
|
||||||
|
|
||||||
// note: we should be offsetting coords, but we can also just subtract from source as well - which is
|
|
||||||
// a win in terms of ops / simplicity (see findFloor, allows us to not modify coords for that)
|
|
||||||
// note: for intersection, one we find the floor of the min we can use that as the start index
|
// note: for intersection, one we find the floor of the min we can use that as the start index
|
||||||
// for the next check as source max >= source min
|
// for the next check as source max >= source min
|
||||||
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
// note: we can fast check intersection on the two other axis by seeing if the min index is >= size,
|
||||||
@@ -856,7 +848,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_x = Math.max(
|
final int floor_min_x = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_x, (source.minX - off_x) + COLLISION_EPSILON, 0, size_x)
|
findFloor(coords_x, off_x, source.minX + COLLISION_EPSILON, 0, size_x)
|
||||||
);
|
);
|
||||||
if (floor_min_x >= size_x) {
|
if (floor_min_x >= size_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -865,7 +857,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_x = Math.min(
|
final int ceil_max_x = Math.min(
|
||||||
size_x,
|
size_x,
|
||||||
findFloor(coords_x, (source.maxX - off_x) - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
findFloor(coords_x, off_x, source.maxX - COLLISION_EPSILON, floor_min_x, size_x) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_x >= ceil_max_x) {
|
if (floor_min_x >= ceil_max_x) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -874,7 +866,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int floor_min_y = Math.max(
|
final int floor_min_y = Math.max(
|
||||||
0,
|
0,
|
||||||
findFloor(coords_y, (source.minY - off_y) + COLLISION_EPSILON, 0, size_y)
|
findFloor(coords_y, off_y, source.minY + COLLISION_EPSILON, 0, size_y)
|
||||||
);
|
);
|
||||||
if (floor_min_y >= size_y) {
|
if (floor_min_y >= size_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -883,7 +875,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int ceil_max_y = Math.min(
|
final int ceil_max_y = Math.min(
|
||||||
size_y,
|
size_y,
|
||||||
findFloor(coords_y, (source.maxY - off_y) - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
findFloor(coords_y, off_y, source.maxY - COLLISION_EPSILON, floor_min_y, size_y) + 1
|
||||||
);
|
);
|
||||||
if (floor_min_y >= ceil_max_y) {
|
if (floor_min_y >= ceil_max_y) {
|
||||||
// cannot intersect
|
// cannot intersect
|
||||||
@@ -895,9 +887,9 @@ public final class CollisionUtil {
|
|||||||
final long[] bitset = cached_shape_data.voxelSet();
|
final long[] bitset = cached_shape_data.voxelSet();
|
||||||
|
|
||||||
if (source_move > 0.0) {
|
if (source_move > 0.0) {
|
||||||
final double source_max = source.maxZ - off_z;
|
final double source_max = source.maxZ;
|
||||||
final int ceil_max_z = findFloor(
|
final int ceil_max_z = findFloor(
|
||||||
coords_z, source_max - COLLISION_EPSILON, 0, size_z
|
coords_z, off_z, source_max - COLLISION_EPSILON, 0, size_z
|
||||||
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
) + 1; // add one, we are not interested in (coords[i] + COLLISION_EPSILON) < max
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -906,7 +898,7 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_z = ceil_max_z; curr_z < size_z; ++curr_z) {
|
for (int curr_z = ceil_max_z; curr_z < size_z; ++curr_z) {
|
||||||
double max_dist = coords_z[curr_z] - source_max;
|
double max_dist = (coords_z[curr_z] + off_z) - source_max;
|
||||||
if (max_dist >= source_move) {
|
if (max_dist >= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
// coords[curr + n] - source_max < source_move, as coords[curr + n] < coords[curr + n + 1]
|
||||||
@@ -933,9 +925,9 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
return source_move;
|
return source_move;
|
||||||
} else {
|
} else {
|
||||||
final double source_min = source.minZ - off_z;
|
final double source_min = source.minZ;
|
||||||
final int floor_min_z = findFloor(
|
final int floor_min_z = findFloor(
|
||||||
coords_z, source_min + COLLISION_EPSILON, 0, size_z
|
coords_z, off_z, source_min + COLLISION_EPSILON, 0, size_z
|
||||||
);
|
);
|
||||||
|
|
||||||
// note: only the order of the first loop matters
|
// note: only the order of the first loop matters
|
||||||
@@ -947,7 +939,7 @@ public final class CollisionUtil {
|
|||||||
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
// thus, we need to use the voxel index i-1 if we want to check that the face at index i is solid
|
||||||
final int mul_x = size_y*size_z;
|
final int mul_x = size_y*size_z;
|
||||||
for (int curr_z = floor_min_z - 1; curr_z >= 0; --curr_z) {
|
for (int curr_z = floor_min_z - 1; curr_z >= 0; --curr_z) {
|
||||||
double max_dist = coords_z[curr_z + 1] - source_min;
|
double max_dist = (coords_z[curr_z + 1] + off_z) - source_min;
|
||||||
if (max_dist <= source_move) {
|
if (max_dist <= source_move) {
|
||||||
// if we reach here, then we will never have a case where
|
// if we reach here, then we will never have a case where
|
||||||
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
// coords[curr + n] - source_max > source_move, as coords[curr + n] > coords[curr + n - 1]
|
||||||
@@ -982,7 +974,7 @@ public final class CollisionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// does not use epsilon
|
// does not use epsilon
|
||||||
public static boolean strictlyContains(final VoxelShape voxel, double x, double y, double z) {
|
public static boolean strictlyContains(final VoxelShape voxel, final double x, final double y, final double z) {
|
||||||
final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation();
|
final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation();
|
||||||
if (single_aabb != null) {
|
if (single_aabb != null) {
|
||||||
return single_aabb.contains(x, y, z);
|
return single_aabb.contains(x, y, z);
|
||||||
@@ -993,10 +985,9 @@ public final class CollisionUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset input
|
final double off_x = ((CollisionVoxelShape)voxel).moonrise$offsetX();
|
||||||
x -= ((CollisionVoxelShape)voxel).moonrise$offsetX();
|
final double off_y = ((CollisionVoxelShape)voxel).moonrise$offsetY();
|
||||||
y -= ((CollisionVoxelShape)voxel).moonrise$offsetY();
|
final double off_z = ((CollisionVoxelShape)voxel).moonrise$offsetZ();
|
||||||
z -= ((CollisionVoxelShape)voxel).moonrise$offsetZ();
|
|
||||||
|
|
||||||
final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX();
|
final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX();
|
||||||
final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY();
|
final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY();
|
||||||
@@ -1012,17 +1003,17 @@ public final class CollisionUtil {
|
|||||||
// note: should mirror AABB#contains, which is that for any point X that X >= min and X < max.
|
// note: should mirror AABB#contains, which is that for any point X that X >= min and X < max.
|
||||||
// specifically, it cannot collide on the max bounds of the shape
|
// specifically, it cannot collide on the max bounds of the shape
|
||||||
|
|
||||||
final int index_x = findFloor(coords_x, x, 0, size_x);
|
final int index_x = findFloor(coords_x, off_x, x, 0, size_x);
|
||||||
if (index_x < 0 || index_x >= size_x) {
|
if (index_x < 0 || index_x >= size_x) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int index_y = findFloor(coords_y, y, 0, size_y);
|
final int index_y = findFloor(coords_y, off_y, y, 0, size_y);
|
||||||
if (index_y < 0 || index_y >= size_y) {
|
if (index_y < 0 || index_y >= size_y) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int index_z = findFloor(coords_z, z, 0, size_z);
|
final int index_z = findFloor(coords_z, off_z, z, 0, size_z);
|
||||||
if (index_z < 0 || index_z >= size_z) {
|
if (index_z < 0 || index_z >= size_z) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1695,74 +1686,56 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
public static double performAABBCollisionsX(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
public static double performAABBCollisionsX(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final AABB target = potentialCollisions.get(i);
|
final AABB target = potentialCollisions.get(i);
|
||||||
value = collideX(target, currentBoundingBox, value);
|
value = collideX(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double performAABBCollisionsY(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
public static double performAABBCollisionsY(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final AABB target = potentialCollisions.get(i);
|
final AABB target = potentialCollisions.get(i);
|
||||||
value = collideY(target, currentBoundingBox, value);
|
value = collideY(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double performAABBCollisionsZ(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
public static double performAABBCollisionsZ(final AABB currentBoundingBox, double value, final List<AABB> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final AABB target = potentialCollisions.get(i);
|
final AABB target = potentialCollisions.get(i);
|
||||||
value = collideZ(target, currentBoundingBox, value);
|
value = collideZ(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double performVoxelCollisionsX(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
public static double performVoxelCollisionsX(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final VoxelShape target = potentialCollisions.get(i);
|
final VoxelShape target = potentialCollisions.get(i);
|
||||||
value = collideX(target, currentBoundingBox, value);
|
value = collideX(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double performVoxelCollisionsY(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
public static double performVoxelCollisionsY(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final VoxelShape target = potentialCollisions.get(i);
|
final VoxelShape target = potentialCollisions.get(i);
|
||||||
value = collideY(target, currentBoundingBox, value);
|
value = collideY(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double performVoxelCollisionsZ(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
public static double performVoxelCollisionsZ(final AABB currentBoundingBox, double value, final List<VoxelShape> potentialCollisions) {
|
||||||
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
for (int i = 0, len = potentialCollisions.size(); i < len; ++i) {
|
||||||
if (Math.abs(value) < COLLISION_EPSILON) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
final VoxelShape target = potentialCollisions.get(i);
|
final VoxelShape target = potentialCollisions.get(i);
|
||||||
value = collideZ(target, currentBoundingBox, value);
|
value = collideZ(target, currentBoundingBox, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3 performVoxelCollisions(final Vec3 moveVector, AABB axisalignedbb, final List<VoxelShape> potentialCollisions) {
|
public static Vec3 performVoxelCollisions(final Vec3 moveVector, AABB axisalignedbb, final List<VoxelShape> potentialCollisions) {
|
||||||
@@ -2168,10 +2141,16 @@ public final class CollisionUtil {
|
|||||||
|
|
||||||
public CollisionContext getDelegate() {
|
public CollisionContext getDelegate() {
|
||||||
this.delegated = true;
|
this.delegated = true;
|
||||||
final Entity entity = this.getEntity();
|
final Entity entity = super.getEntity();
|
||||||
return this.delegate == null ? this.delegate = (entity == null ? CollisionContext.empty() : CollisionContext.of(entity)) : this.delegate;
|
return this.delegate == null ? this.delegate = (entity == null ? CollisionContext.empty() : CollisionContext.of(entity)) : this.delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity getEntity() {
|
||||||
|
this.getDelegate();
|
||||||
|
return super.getEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDescending() {
|
public boolean isDescending() {
|
||||||
return this.getDelegate().isDescending();
|
return this.getDelegate().isDescending();
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ public final class MoonriseCommand {
|
|||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
ctx.getSource().sendFailure(
|
ctx.getSource().sendFailure(
|
||||||
Component.literal("Reloaded Moonrise config.")
|
Component.literal("Failed to reload Moonrise config, see logs.")
|
||||||
.withStyle(ChatFormatting.RED)
|
.withStyle(ChatFormatting.RED)
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ accessible field net/minecraft/world/level/chunk/PalettedContainer data Lnet/min
|
|||||||
|
|
||||||
# PalettedContainer.Data
|
# PalettedContainer.Data
|
||||||
accessible class net/minecraft/world/level/chunk/PalettedContainer$Data
|
accessible class net/minecraft/world/level/chunk/PalettedContainer$Data
|
||||||
|
# MDG requires we AT the constructor if we AT the class
|
||||||
|
accessible method net/minecraft/world/level/chunk/PalettedContainer$Data <init> (Lnet/minecraft/world/level/chunk/PalettedContainer$Configuration;Lnet/minecraft/util/BitStorage;Lnet/minecraft/world/level/chunk/Palette;)V
|
||||||
|
|
||||||
|
|
||||||
# PaletteResize
|
# PaletteResize
|
||||||
@@ -150,6 +152,11 @@ accessible method net/minecraft/world/level/material/Fluid isEmpty ()Z
|
|||||||
accessible method net/minecraft/world/level/material/Fluid createLegacyBlock (Lnet/minecraft/world/level/material/FluidState;)Lnet/minecraft/world/level/block/state/BlockState;
|
accessible method net/minecraft/world/level/material/Fluid createLegacyBlock (Lnet/minecraft/world/level/material/FluidState;)Lnet/minecraft/world/level/block/state/BlockState;
|
||||||
accessible method net/minecraft/world/level/material/Fluid isRandomlyTicking ()Z
|
accessible method net/minecraft/world/level/material/Fluid isRandomlyTicking ()Z
|
||||||
|
|
||||||
|
# We need to manually copy these down for MDG
|
||||||
|
accessible method net/minecraft/world/level/material/EmptyFluid isEmpty ()Z
|
||||||
|
accessible method net/minecraft/world/level/material/EmptyFluid createLegacyBlock (Lnet/minecraft/world/level/material/FluidState;)Lnet/minecraft/world/level/block/state/BlockState;
|
||||||
|
accessible method net/minecraft/world/level/material/LavaFluid createLegacyBlock (Lnet/minecraft/world/level/material/FluidState;)Lnet/minecraft/world/level/block/state/BlockState;
|
||||||
|
accessible method net/minecraft/world/level/material/LavaFluid isRandomlyTicking ()Z
|
||||||
|
|
||||||
# VisibilitySet
|
# VisibilitySet
|
||||||
accessible field net/minecraft/client/renderer/chunk/VisibilitySet FACINGS I
|
accessible field net/minecraft/client/renderer/chunk/VisibilitySet FACINGS I
|
||||||
@@ -305,3 +312,5 @@ accessible class net/minecraft/world/level/LocalMobCapCalculator$MobCounts
|
|||||||
|
|
||||||
# SectionStorage$PackedChunk
|
# SectionStorage$PackedChunk
|
||||||
accessible class net/minecraft/world/level/chunk/storage/SectionStorage$PackedChunk
|
accessible class net/minecraft/world/level/chunk/storage/SectionStorage$PackedChunk
|
||||||
|
# MDG requires we AT the constructor if we AT the class
|
||||||
|
accessible method net/minecraft/world/level/chunk/storage/SectionStorage$PackedChunk <init> (Lit/unimi/dsi/fastutil/ints/Int2ObjectMap;Z)V
|
||||||
|
|||||||
@@ -1,143 +1,145 @@
|
|||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "ca.spottedleaf.moonrise.mixin",
|
"package": "ca.spottedleaf.moonrise.mixin",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"bitstorage.SimpleBitStorageMixin",
|
"bitstorage.SimpleBitStorageMixin",
|
||||||
"bitstorage.ZeroBitStorageMixin",
|
"bitstorage.ZeroBitStorageMixin",
|
||||||
"block_counting.BitStorageMixin",
|
"block_counting.BitStorageMixin",
|
||||||
"block_counting.LevelChunkSectionMixin",
|
"block_counting.LevelChunkSectionMixin",
|
||||||
"block_counting.SimpleBitStorageMixin",
|
"block_counting.SimpleBitStorageMixin",
|
||||||
"block_counting.ZeroBitStorageMixin",
|
"block_counting.ZeroBitStorageMixin",
|
||||||
"block_entity_remove.LevelMixin",
|
"block_entity_remove.LevelMixin",
|
||||||
"blockstate_propertyaccess.BooleanPropertyMixin",
|
"blockstate_propertyaccess.BooleanPropertyMixin",
|
||||||
"blockstate_propertyaccess.EnumPropertyMixin",
|
"blockstate_propertyaccess.EnumPropertyMixin",
|
||||||
"blockstate_propertyaccess.IntegerPropertyMixin",
|
"blockstate_propertyaccess.IntegerPropertyMixin",
|
||||||
"blockstate_propertyaccess.PropertyMixin",
|
"blockstate_propertyaccess.PropertyMixin",
|
||||||
"blockstate_propertyaccess.StateHolderMixin",
|
"blockstate_propertyaccess.StateHolderMixin",
|
||||||
"chunk_system.ChunkBufferMixin",
|
"chunk_system.ChunkBufferMixin",
|
||||||
"chunk_system.ChunkGeneratorMixin",
|
"chunk_system.ChunkGeneratorMixin",
|
||||||
"chunk_system.ChunkHolderMixin",
|
"chunk_system.ChunkHolderMixin",
|
||||||
"chunk_system.ChunkMap$DistanceManagerMixin",
|
"chunk_system.ChunkMap$DistanceManagerMixin",
|
||||||
"chunk_system.ChunkMapMixin",
|
"chunk_system.ChunkMapMixin",
|
||||||
"chunk_system.ChunkPyramidMixin",
|
"chunk_system.ChunkPyramidMixin",
|
||||||
"chunk_system.ChunkStatusMixin",
|
"chunk_system.ChunkStatusMixin",
|
||||||
"chunk_system.ChunkStepMixin",
|
"chunk_system.ChunkStepMixin",
|
||||||
"chunk_system.ChunkStorageMixin",
|
"chunk_system.ChunkStorageMixin",
|
||||||
"chunk_system.DistanceManagerMixin",
|
"chunk_system.DistanceManagerMixin",
|
||||||
"chunk_system.EntityGetterMixin",
|
"chunk_system.EntityGetterMixin",
|
||||||
"chunk_system.EntityMixin",
|
"chunk_system.EntityMixin",
|
||||||
"chunk_system.EntityTickListMixin",
|
"chunk_system.EntityTickListMixin",
|
||||||
"chunk_system.GenerationChunkHolderMixin",
|
"chunk_system.GenerationChunkHolderMixin",
|
||||||
"chunk_system.LevelChunkMixin",
|
"chunk_system.LevelChunkMixin",
|
||||||
"chunk_system.LevelChunkTicksMixin",
|
"chunk_system.LevelChunkTicksMixin",
|
||||||
"chunk_system.LevelMixin",
|
"chunk_system.LevelMixin",
|
||||||
"chunk_system.LevelReaderMixin",
|
"chunk_system.LevelReaderMixin",
|
||||||
"chunk_system.MinecraftServerMixin",
|
"chunk_system.MinecraftServerMixin",
|
||||||
"chunk_system.NoiseBasedChunkGeneratorMixin",
|
"chunk_system.NoiseBasedChunkGeneratorMixin",
|
||||||
"chunk_system.PlayerListMixin",
|
"chunk_system.PlayerListMixin",
|
||||||
"chunk_system.PoiManagerMixin",
|
"chunk_system.PoiManagerMixin",
|
||||||
"chunk_system.PoiSectionMixin",
|
"chunk_system.PoiSectionMixin",
|
||||||
"chunk_system.RegionFileMixin",
|
"chunk_system.RegionFileMixin",
|
||||||
"chunk_system.RegionFileStorageMixin",
|
"chunk_system.RegionFileStorageMixin",
|
||||||
"chunk_system.SectionStorageMixin",
|
"chunk_system.SectionStorageMixin",
|
||||||
"chunk_system.SerializableChunkDataMixin",
|
"chunk_system.SerializableChunkDataMixin",
|
||||||
"chunk_system.ServerChunkCache$MainThreadExecutorMixin",
|
"chunk_system.ServerChunkCache$MainThreadExecutorMixin",
|
||||||
"chunk_system.ServerChunkCacheMixin",
|
"chunk_system.ServerChunkCacheMixin",
|
||||||
"chunk_system.ServerLevelMixin",
|
"chunk_system.ServerLevelMixin",
|
||||||
"chunk_system.ServerPlayerMixin",
|
"chunk_system.ServerPlayerMixin",
|
||||||
"chunk_system.SortedArraySetMixin",
|
"chunk_system.SortedArraySetMixin",
|
||||||
"chunk_system.StructureCheckMixin",
|
"chunk_system.StructureCheckMixin",
|
||||||
"chunk_system.StructureTemplate$PaletteMixin",
|
"chunk_system.StructureTemplate$PaletteMixin",
|
||||||
"chunk_system.TicketMixin",
|
"chunk_system.TicketMixin",
|
||||||
"chunk_tick_iteration.ChunkMapMixin",
|
"chunk_tick_iteration.ChunkMapMixin",
|
||||||
"chunk_tick_iteration.DistanceManagerMixin",
|
"chunk_tick_iteration.DistanceManagerMixin",
|
||||||
"chunk_tick_iteration.ServerChunkCacheMixin",
|
"chunk_tick_iteration.ServerChunkCacheMixin",
|
||||||
"chunk_tick_iteration.ServerLevelMixin",
|
"chunk_tick_iteration.ServerLevelMixin",
|
||||||
"collisions.ArmorStandMixin",
|
"collisions.ArmorStandMixin",
|
||||||
"collisions.ArrayVoxelShapeMixin",
|
"collisions.ArrayVoxelShapeMixin",
|
||||||
"collisions.BitSetDiscreteVoxelShapeMixin",
|
"collisions.BitSetDiscreteVoxelShapeMixin",
|
||||||
"collisions.BlockMixin",
|
"collisions.BlockMixin",
|
||||||
"collisions.BlockPosMixin",
|
"collisions.BlockPosMixin",
|
||||||
"collisions.BlockStateBaseMixin",
|
"collisions.BlockStateBaseMixin",
|
||||||
"collisions.CubeVoxelShapeMixin",
|
"collisions.CubeVoxelShapeMixin",
|
||||||
"collisions.DirectionMixin",
|
"collisions.DirectionMixin",
|
||||||
"collisions.DiscreteVoxelShapeMixin",
|
"collisions.DiscreteVoxelShapeMixin",
|
||||||
"collisions.EntityGetterMixin",
|
"collisions.EntityGetterMixin",
|
||||||
"collisions.EntityMixin",
|
"collisions.EntityMixin",
|
||||||
"collisions.LevelMixin",
|
"collisions.LevelMixin",
|
||||||
"collisions.ServerEntityMixin",
|
"collisions.ServerEntityMixin",
|
||||||
"collisions.ServerExplosionMixin",
|
"collisions.ServerExplosionMixin",
|
||||||
"collisions.ShapesMixin",
|
"collisions.ShapesMixin",
|
||||||
"collisions.SliceShapeMixin",
|
"collisions.SliceShapeMixin",
|
||||||
"collisions.VoxelShapeMixin",
|
"collisions.VoxelShapeMixin",
|
||||||
"command.CommandsMixin",
|
"command.CommandsMixin",
|
||||||
"config.MinecraftServerMixin",
|
"config.MinecraftServerMixin",
|
||||||
"end_island.DensityFunctions$EndIslandDensityFunctionMixin",
|
"end_island.DensityFunctions$EndIslandDensityFunctionMixin",
|
||||||
"entity_tracker.ChunkMapMixin",
|
"entity_tracker.ChunkMapMixin",
|
||||||
"entity_tracker.EntityMixin",
|
"entity_tracker.EntityMixin",
|
||||||
"entity_tracker.TrackedEntityMixin",
|
"entity_tracker.TrackedEntityMixin",
|
||||||
"fast_palette.CrudeIncrementalIntIdentityHashBiMapMixin",
|
"fast_palette.CrudeIncrementalIntIdentityHashBiMapMixin",
|
||||||
"fast_palette.HashMapPaletteMixin",
|
"fast_palette.HashMapPaletteMixin",
|
||||||
"fast_palette.LinearPaletteMixin",
|
"fast_palette.LinearPaletteMixin",
|
||||||
"fast_palette.PalettedContainer$DataMixin",
|
"fast_palette.PalettedContainer$DataMixin",
|
||||||
"fast_palette.PalettedContainerMixin",
|
"fast_palette.PalettedContainerMixin",
|
||||||
"fast_palette.PaletteMixin",
|
"fast_palette.PaletteMixin",
|
||||||
"fast_palette.SingleValuePaletteMixin",
|
"fast_palette.SingleValuePaletteMixin",
|
||||||
"fluid.FlowingFluidMixin",
|
"fluid.FlowingFluidMixin",
|
||||||
"fluid.FluidStateMixin",
|
"fluid.FluidStateMixin",
|
||||||
"fluid.MappedRegistryMixin",
|
"fluid.MappedRegistryMixin",
|
||||||
"getblock.ChunkAccessMixin",
|
"getblock.ChunkAccessMixin",
|
||||||
"getblock.LevelChunkMixin",
|
"getblock.LevelChunkMixin",
|
||||||
"getblock.LevelMixin",
|
"getblock.LevelMixin",
|
||||||
"keep_alive_client.ServerGamePacketListenerImplMixin",
|
"keep_alive_client.ServerGamePacketListenerImplMixin",
|
||||||
"mob_spawning.EntityTypeMixin",
|
"mob_spawning.EntityTypeMixin",
|
||||||
"mob_spawning.LocalMobCapCalculator$MobCountsMixin",
|
"mob_spawning.LocalMobCapCalculator$MobCountsMixin",
|
||||||
"mob_spawning.MobSpawnSettingsMixin",
|
"mob_spawning.MobSpawnSettingsMixin",
|
||||||
"mob_spawning.NaturalSpawnerMixin",
|
"mob_spawning.NaturalSpawnerMixin",
|
||||||
"poi_lookup.AcquirePoiMixin",
|
"poi_lookup.AcquirePoiMixin",
|
||||||
"poi_lookup.PoiManagerMixin",
|
"poi_lookup.PoiManagerMixin",
|
||||||
"poi_lookup.PortalForcerMixin",
|
"poi_lookup.PortalForcerMixin",
|
||||||
"random_ticking.BiomeManagerMixin",
|
"random.EntityMixin",
|
||||||
"random_ticking.BiomeMixin",
|
"random.LevelMixin",
|
||||||
"random_ticking.LevelMixin",
|
"random_ticking.BiomeManagerMixin",
|
||||||
"random_ticking.ServerLevelMixin",
|
"random_ticking.BiomeMixin",
|
||||||
"serverlist.ConnectionMixin",
|
"random_ticking.LevelMixin",
|
||||||
"starlight.blockstate.BlockStateBaseMixin",
|
"random_ticking.ServerLevelMixin",
|
||||||
"starlight.chunk.ChunkAccessMixin",
|
"serverlist.ConnectionMixin",
|
||||||
"starlight.chunk.EmptyLevelChunkMixin",
|
"starlight.blockstate.BlockStateBaseMixin",
|
||||||
"starlight.chunk.ImposterProtoChunkMixin",
|
"starlight.chunk.ChunkAccessMixin",
|
||||||
"starlight.chunk.LevelChunkMixin",
|
"starlight.chunk.EmptyLevelChunkMixin",
|
||||||
"starlight.chunk.ProtoChunkMixin",
|
"starlight.chunk.ImposterProtoChunkMixin",
|
||||||
"starlight.lightengine.LevelLightEngineMixin",
|
"starlight.chunk.LevelChunkMixin",
|
||||||
"starlight.lightengine.ThreadedLevelLightEngineMixin",
|
"starlight.chunk.ProtoChunkMixin",
|
||||||
"starlight.world.SerializableChunkData$SectionData",
|
"starlight.lightengine.LevelLightEngineMixin",
|
||||||
"starlight.world.SerializableChunkDataMixin",
|
"starlight.lightengine.ThreadedLevelLightEngineMixin",
|
||||||
"starlight.world.WorldGenRegionMixin",
|
"starlight.world.SerializableChunkData$SectionData",
|
||||||
"util_thread_counts.UtilMixin",
|
"starlight.world.SerializableChunkDataMixin",
|
||||||
"util_threading_detector.PalettedContainerMixin",
|
"starlight.world.WorldGenRegionMixin",
|
||||||
"util_threading_detector.ThreadingDetectorMixin",
|
"util_thread_counts.UtilMixin",
|
||||||
"util_time_source.UtilMixin"
|
"util_threading_detector.PalettedContainerMixin",
|
||||||
],
|
"util_threading_detector.ThreadingDetectorMixin",
|
||||||
"client": [
|
"util_time_source.UtilMixin"
|
||||||
"chunk_system.ClientLevelMixin",
|
],
|
||||||
"chunk_system.OptionsMixin",
|
"client": [
|
||||||
"collisions.LiquidBlockRendererMixin",
|
"chunk_system.ClientLevelMixin",
|
||||||
"collisions.ParticleMixin",
|
"chunk_system.OptionsMixin",
|
||||||
"config.MinecraftMixin",
|
"collisions.LiquidBlockRendererMixin",
|
||||||
"loading_screen.LevelLoadStatusManagerMixin",
|
"collisions.ParticleMixin",
|
||||||
"profiler.MinecraftMixin",
|
"config.MinecraftMixin",
|
||||||
"render.SectionRenderDispatcherMixin",
|
"loading_screen.LevelLoadStatusManagerMixin",
|
||||||
"serverlist.ClientConnectionMixin",
|
"profiler.MinecraftMixin",
|
||||||
"serverlist.ServerAddressResolverMixin",
|
"render.SectionRenderDispatcherMixin",
|
||||||
"serverlist.ServerSelectionListMixin",
|
"serverlist.ClientConnectionMixin",
|
||||||
"starlight.multiplayer.ClientPacketListenerMixin"
|
"serverlist.ServerAddressResolverMixin",
|
||||||
],
|
"serverlist.ServerSelectionListMixin",
|
||||||
"injectors": {
|
"starlight.multiplayer.ClientPacketListenerMixin"
|
||||||
"defaultRequire": 1
|
],
|
||||||
},
|
"injectors": {
|
||||||
"overwrites": {
|
"defaultRequire": 1
|
||||||
"conformVisibility": true
|
},
|
||||||
|
"overwrites": {
|
||||||
|
"conformVisibility": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user