Compare commits

..

2 Commits

Author SHA1 Message Date
Jason Penilla
81927092f1 Bump resource-factory 2025-05-14 09:08:26 -07:00
Jason Penilla
0f0da2998a Generate mod metadata files with resource factory instead of using processResources 2025-05-10 15:34:00 -07:00
38 changed files with 248 additions and 509 deletions

View File

@@ -4,6 +4,7 @@ plugins {
id("java-library")
id("net.neoforged.moddev")
id("me.modmuss50.mod-publish-plugin") version "0.8.4" apply false
id("xyz.jpenilla.resource-factory") version "1.3.0" apply false
}
extensions.create("runConfigCommon", RunConfigCommon.class)

View File

@@ -1,15 +1,11 @@
import java.util.stream.Collectors
import net.fabricmc.loom.util.gradle.SourceSetHelper
import xyz.jpenilla.resourcefactory.fabric.Environment
plugins {
id("quiet-fabric-loom")
id 'maven-publish'
}
boolean gui = enable_gui == "true"
if (gui) {
sourceSets.create("gui")
loom.createRemapConfigurations(sourceSets.gui)
id 'xyz.jpenilla.resource-factory-fabric-convention'
}
dependencies {
@@ -26,16 +22,9 @@ dependencies {
libs("ca.spottedleaf:yamlconfig:${rootProject.yamlconfig_version}") { setTransitive(false) }
libs("org.yaml:snakeyaml:${rootProject.snakeyaml_version}")
if (gui) {
guiCompileOnly(project(":"))
runtimeOnly(sourceSets.gui.output)
shadow(sourceSets.gui.output)
modGuiImplementation "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_version}"
modRuntimeOnly "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}"
modGuiImplementation "com.terraformersmc:modmenu:${rootProject.modmenu_version}"
modRuntimeOnly "com.terraformersmc:modmenu:${rootProject.modmenu_version}"
}
modImplementation "com.terraformersmc:modmenu:${rootProject.modmenu_version}"
modImplementation platform(fabricApiLibs.bom)
modImplementation fabricApiLibs.command.api.v2
@@ -44,27 +33,6 @@ dependencies {
include fabricApiLibs.base
}
if (gui) {
afterEvaluate {
configurations.guiCompileOnly {
extendsFrom configurations.getByName("minecraftNamedCompile")
}
}
}
tasks.processResources {
def properties = [
"version": project.version,
"minecraft_version": minecraft_version,
"loader_version": loader_version,
"mod_version": mod_version
]
inputs.properties(properties)
filesMatching("fabric.mod.json") {
expand properties
}
}
tasks.shadowJar {
archiveClassifier = "dev-all"
destinationDirectory = layout.buildDirectory.dir("libs")
@@ -74,6 +42,72 @@ tasks.shadowJar {
relocate 'org.yaml.snakeyaml', 'ca.spottedleaf.moonrise.libs.org.yaml.snakeyaml'
}
fabricModJson {
id = "moonrise"
name = "Moonrise"
description = "Optimisation mod for the dedicated and integrated server."
author("Spottedleaf")
contact {
issues = "https://github.com/Tuinity/Moonrise/issues"
sources = "https://github.com/Tuinity/Moonrise"
extra.put("discord", "https://discord.gg/tuinity")
homepage = "https://www.curseforge.com/minecraft/mc-mods/moonrise"
}
breaks("notenoughcrashes")
breaks("starlight")
breaks("c2me")
license("GPL-3.0-only")
icon("assets/moonrise/icon.png")
environment = Environment.ANY
clientEntrypoint("ca.spottedleaf.moonrise.fabric.MoonriseFabricClient")
entrypoint("modmenu", "ca.spottedleaf.moonrise.fabric.MoonriseModMenuHook")
mixin("moonrise.mixins.json")
mixin("moonrise-fabric.mixins.json")
accessWidener = "moonrise.accesswidener"
depends("fabricloader", ">=${loader_version}")
depends("minecraft", ">1.21.4 <1.21.6")
depends("fabric-command-api-v2", "*")
custom.put(
"ferritecore:disabled_options",
simpleCustomValueList(String, ["replaceNeighborLookup", "replacePropertyMap"])
)
custom.put(
"lithium:options",
simpleCustomValueMap(
String,
Boolean,
[
"mixin.ai.poi": false,
"mixin.alloc.deep_passengers": false,
"mixin.alloc.entity_tracker": false,
"mixin.block.flatten_states": false,
"mixin.chunk.entity_class_groups": false,
"mixin.chunk.no_validation": false,
"mixin.collections.chunk_tickets": false,
"mixin.collections.entity_ticking": false,
"mixin.entity.collisions.intersection": false,
"mixin.entity.collisions.movement": false,
"mixin.entity.collisions.unpushable_cramming": false,
"mixin.entity.replace_entitytype_predicates": false,
"mixin.math.fast_blockpos": false,
"mixin.math.fast_util": false,
"mixin.minimal_nonvanilla.collisions.empty_space": false,
"mixin.minimal_nonvanilla.world.expiring_chunk_tickets": false,
"mixin.shapes.blockstate_cache": false,
"mixin.shapes.optimized_matching": false,
"mixin.shapes.specialized_shapes": false,
"mixin.util.block_tracking": false,
"mixin.util.entity_movement_tracking": false,
"mixin.world.block_entity_ticking": false,
"mixin.world.chunk_access": false,
"mixin.world.explosions.block_raycast": false,
"mixin.world.temperature_cache": false,
"mixin.world.tick_scheduler": false,
]
)
)
}
publishMods {
file = remapJar.archiveFile
modLoaders = ["fabric"]

View File

@@ -6,7 +6,6 @@ import ca.spottedleaf.moonrise.common.util.ConfigHolder;
import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFixer;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.longs.LongArrays;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
@@ -19,7 +18,6 @@ import net.minecraft.server.level.GenerationChunkHolder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.TicketType;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.level.BlockGetter;
@@ -33,9 +31,7 @@ import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.status.ChunkStatusTasks;
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.phys.AABB;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
@@ -44,8 +40,6 @@ public final class FabricHooks extends BaseChunkSystemHooks implements PlatformH
private static final boolean HAS_FABRIC_LIFECYCLE_EVENTS = FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1");
private static final Logger LOGGER = LogUtils.getLogger();
@Override
public String getBrand() {
return "Moonrise";
@@ -257,9 +251,7 @@ public final class FabricHooks extends BaseChunkSystemHooks implements PlatformH
@Override
public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) {
ChunkStatusTasks.postLoadProtoChunk(world, TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities()));
}
ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
}
@Override
@@ -271,9 +263,4 @@ public final class FabricHooks extends BaseChunkSystemHooks implements PlatformH
public long[] getCounterTypesUncached(final TicketType type) {
return type == TicketType.FORCED ? new long[] { ChunkSystemTicketType.COUNTER_TYPE_FORCED } : LongArrays.EMPTY_ARRAY;
}
@Override
public boolean addTicketForEnderPearls() {
return true;
}
}

View File

@@ -1,76 +0,0 @@
{
"schemaVersion": 1,
"id": "moonrise",
"version": "${version}",
"name": "Moonrise",
"description": "Optimisation mod for the dedicated and integrated server.",
"authors": [
"Spottedleaf"
],
"contact": {
"issues": "https://github.com/Tuinity/Moonrise/issues",
"sources": "https://github.com/Tuinity/Moonrise",
"discord": "https://discord.gg/tuinity",
"homepage": "https://www.curseforge.com/minecraft/mc-mods/moonrise"
},
"breaks": {
"notenoughcrashes": "*",
"starlight": "*",
"c2me": "*"
},
"license": "GPL-3.0-only",
"icon": "assets/moonrise/icon.png",
"environment": "*",
"entrypoints": {
"modmenu": [
"ca.spottedleaf.moonrise.fabric.MoonriseModMenuHook"
],
"client": [
"ca.spottedleaf.moonrise.fabric.MoonriseFabricClient"
]
},
"mixins": [
"moonrise.mixins.json",
"moonrise-fabric.mixins.json"
],
"accessWidener": "moonrise.accesswidener",
"depends": {
"fabricloader": ">=${loader_version}",
"minecraft": ">1.21.5 <1.21.7",
"fabric-command-api-v2": "*"
},
"custom": {
"lithium:options": {
"mixin.ai.poi": false,
"mixin.alloc.deep_passengers": false,
"mixin.alloc.entity_tracker": false,
"mixin.block.flatten_states": false,
"mixin.chunk.entity_class_groups": false,
"mixin.chunk.no_validation": false,
"mixin.collections.chunk_tickets": false,
"mixin.collections.entity_ticking": false,
"mixin.entity.collisions.intersection": false,
"mixin.entity.collisions.movement": false,
"mixin.entity.collisions.unpushable_cramming": false,
"mixin.entity.replace_entitytype_predicates": false,
"mixin.math.fast_blockpos": false,
"mixin.math.fast_util": false,
"mixin.minimal_nonvanilla.collisions.empty_space": false,
"mixin.minimal_nonvanilla.world.expiring_chunk_tickets": false,
"mixin.shapes.blockstate_cache": false,
"mixin.shapes.optimized_matching": false,
"mixin.shapes.specialized_shapes": false,
"mixin.util.block_tracking": false,
"mixin.util.entity_movement_tracking": false,
"mixin.world.block_entity_ticking": false,
"mixin.world.chunk_access": false,
"mixin.world.explosions.block_raycast": false,
"mixin.world.temperature_cache": false,
"mixin.world.tick_scheduler": false
},
"ferritecore:disabled_options": [
"replaceNeighborLookup",
"replacePropertyMap"
]
}
}

View File

@@ -4,25 +4,23 @@ org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
# Fabric Properties
# check these on https://fabricmc.net/develop/
minecraft_version=1.21.6
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.21.5
loader_version=0.16.14
supported_minecraft_versions=1.21.6
neoforge_version=21.6.11-beta
neoform_version=1.21.6-20250617.151856
fabric_api_version=0.127.1+1.21.6
supported_minecraft_versions=1.21.5
neoforge_version=21.5.65-beta
neoform_version=1.21.5-20250325.162830
fabric_api_version=0.123.0+1.21.5
snakeyaml_version=2.3
concurrentutil_version=0.0.3
yamlconfig_version=1.0.2
cloth_version=19.0.147
modmenu_version=15.0.0-beta.2
# set to false when modmenu/cloth is not updated for the current minecraft version
enable_gui=true
cloth_version=18.0.145
modmenu_version=14.0.0-rc.2
junit_version=5.11.3
# version ids from modrinth
fabric_lithium_version=nhc57Td2
neo_lithium_version=P5VT33Jo
# Mod Properties
mod_version=0.4.0-beta.2
mod_version=0.3.0-SNAPSHOT
maven_group=ca.spottedleaf.moonrise
archives_base_name=moonrise

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

6
gradlew vendored
View File

@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -205,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.

4
gradlew.bat vendored
View File

@@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

View File

@@ -5,6 +5,7 @@ import net.neoforged.moddevgradle.internal.RunGameTask
plugins {
id("net.neoforged.moddev")
id 'maven-publish'
id 'xyz.jpenilla.resource-factory-neoforge-convention'
}
repositories {
@@ -57,18 +58,6 @@ dependencies {
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"
}
@@ -94,6 +83,75 @@ tasks.assemble {
dependsOn tasks.productionJar
}
neoForgeModsToml {
license = "GPLv3"
issueTrackerUrl = "https://github.com/Tuinity/Moonrise"
showAsResourcePack = false
mods.register("moonrise") {
setConventionsFromProjectMeta(project)
displayName = "Moonrise"
displayUrl = "https://github.com/Tuinity/Moonrise"
authors = "Spottedleaf"
description = "Optimisation mod for the dedicated and integrated server."
logoFile = "assets/moonrise/icon.png"
custom.put(
"ferritecore:disabled_options",
simpleCustomValueList(String, ["replaceNeighborLookup", "replacePropertyMap"])
)
dependencies {
required("neoforge", "[21.5,)")
required("minecraft", "1.21.5")
incompatible("notenoughcrashes")
incompatible("starlight")
incompatible("c2me")
}
}
mixins(
"moonrise.mixins.json",
"moonrise-neoforge.mixins.json"
)
custom.put(
"lithium:options",
simpleCustomValueMap(
String,
Boolean,
[
"mixin.ai.poi": false,
"mixin.alloc.deep_passengers": false,
"mixin.alloc.entity_tracker": false,
"mixin.block.flatten_states": false,
"mixin.chunk.entity_class_groups": false,
"mixin.chunk.no_validation": false,
"mixin.collections.chunk_tickets": false,
"mixin.collections.entity_ticking": false,
"mixin.entity.collisions.intersection": false,
"mixin.entity.collisions.movement": false,
"mixin.entity.collisions.unpushable_cramming": false,
"mixin.entity.replace_entitytype_predicates": false,
"mixin.math.fast_blockpos": false,
"mixin.math.fast_util": false,
"mixin.minimal_nonvanilla.collisions.empty_space": false,
"mixin.minimal_nonvanilla.world.expiring_chunk_tickets": false,
"mixin.shapes.blockstate_cache": false,
"mixin.shapes.optimized_matching": false,
"mixin.shapes.specialized_shapes": false,
"mixin.util.block_tracking": false,
"mixin.util.entity_movement_tracking": false,
"mixin.world.block_entity_ticking": false,
"mixin.world.chunk_access": false,
"mixin.world.explosions.block_raycast": false,
"mixin.world.temperature_cache": false,
"mixin.world.tick_scheduler": false,
]
)
)
}
publishMods {
file = productionJar.archiveFile
modLoaders = ["neoforge"]

View File

@@ -7,7 +7,6 @@ import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFixer;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import net.minecraft.core.BlockPos;
@@ -18,7 +17,6 @@ import net.minecraft.server.level.GenerationChunkHolder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.TicketType;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
@@ -32,7 +30,6 @@ import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.status.ChunkStatusTasks;
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.CommonHooks;
import net.neoforged.neoforge.common.NeoForge;
@@ -41,15 +38,12 @@ import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.level.ChunkDataEvent;
import net.neoforged.neoforge.event.level.ChunkEvent;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
public final class NeoForgeHooks extends BaseChunkSystemHooks implements PlatformHooks {
private static final Logger LOGGER = LogUtils.getLogger();
@Override
public String getBrand() {
return "Moonrise";
@@ -263,9 +257,7 @@ public final class NeoForgeHooks extends BaseChunkSystemHooks implements Platfor
@Override
public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) {
ChunkStatusTasks.postLoadProtoChunk(world, TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities()));
}
ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
}
@Override
@@ -286,9 +278,4 @@ public final class NeoForgeHooks extends BaseChunkSystemHooks implements Platfor
return ret.toLongArray();
}
@Override
public boolean addTicketForEnderPearls() {
return true;
}
}

View File

@@ -1,84 +0,0 @@
modLoader = "javafml"
loaderVersion = "[1,)"
license = "GPLv3"
issueTrackerURL = "https://github.com/Tuinity/Moonrise"
showAsResourcePack = false
logoFile = "assets/moonrise/icon.png"
[[mods]]
modId = "moonrise"
version = "${version}"
displayName = "Moonrise"
displayURL = "https://github.com/Tuinity/Moonrise"
authors = "Spottedleaf"
description = "Optimisation mod for the dedicated and integrated server."
displayTest = "IGNORE_ALL_VERSION"
"ferritecore:disabled_options" = [
"replaceNeighborLookup",
"replacePropertyMap"
]
[[dependencies.moonrise]]
modId = "neoforge"
type = "required"
versionRange = "[21.0,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.moonrise]]
modId = "minecraft"
type = "required"
versionRange = "(1.21.5,1.21.7)"
ordering = "NONE"
side = "BOTH"
[[dependencies.moonrise]]
modId = "notenoughcrashes"
type = "incompatible"
[[dependencies.moonrise]]
modId = "starlight"
type = "incompatible"
[[dependencies.moonrise]]
# unofficial lithium port
modId = "canary"
type = "incompatible"
[[dependencies.moonrise]]
modId = "c2me"
type = "incompatible"
[[mixins]]
config = "moonrise.mixins.json"
[[mixins]]
config = "moonrise-neoforge.mixins.json"
["lithium:options"]
"mixin.ai.poi" = false
"mixin.alloc.deep_passengers" = false
"mixin.alloc.entity_tracker" = false
"mixin.block.flatten_states" = false
"mixin.chunk.entity_class_groups" = false
"mixin.chunk.no_validation" = false
"mixin.collections.chunk_tickets" = false
"mixin.collections.entity_ticking" = false
"mixin.entity.collisions.intersection" = false
"mixin.entity.collisions.movement" = false
"mixin.entity.collisions.unpushable_cramming" = false
"mixin.entity.replace_entitytype_predicates" = false
"mixin.math.fast_blockpos" = false
"mixin.math.fast_util" = false
"mixin.minimal_nonvanilla.collisions.empty_space" = false
"mixin.minimal_nonvanilla.world.expiring_chunk_tickets" = false
"mixin.shapes.blockstate_cache" = false
"mixin.shapes.optimized_matching" = false
"mixin.shapes.specialized_shapes" = false
"mixin.util.block_tracking" = false
"mixin.util.entity_movement_tracking" = false
"mixin.world.block_entity_ticking" = false
"mixin.world.chunk_access" = false
"mixin.world.explosions.block_raycast" = false
"mixin.world.temperature_cache" = false
"mixin.world.tick_scheduler" = false

View File

@@ -22,7 +22,7 @@ pluginManagement {
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
id("quiet-fabric-loom") version "1.10.317" apply false
id("net.neoforged.moddev") version "2.0.80" apply false
id 'com.gradleup.shadow' version '8.3.6' apply false

View File

@@ -102,8 +102,6 @@ public interface PlatformHooks extends ChunkSystemHooks {
public int modifyEntityTrackingRange(final Entity entity, final int currentRange);
public boolean addTicketForEnderPearls();
public static final class Holder {
private Holder() {
}

View File

@@ -2,7 +2,6 @@ package ca.spottedleaf.moonrise.common.config.moonrise;
import ca.spottedleaf.moonrise.common.config.ui.ClothConfig;
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler;
import ca.spottedleaf.yamlconfig.InitialiseHook;
import ca.spottedleaf.yamlconfig.annotation.Adaptable;
@@ -39,7 +38,7 @@ public final class MoonriseConfig {
@Adaptable
public static final class Basic implements InitialiseHook {
public static final class Basic {
@Serializable(
comment = """
The maximum rate of chunks to send to any given player, per second. If this value is <= 0,
@@ -73,20 +72,6 @@ public final class MoonriseConfig {
section = CHUNK_SYSTEM_SECTION
)
public double playerMaxGenRate = -1.0;
@Serializable(
comment = """
The delay before chunks are unloaded around players once they leave their view distance.
The Vanilla value is 0 ticks. Setting this value higher (i.e 5s) will allow pets to teleport
to their owners when they teleport.
"""
)
public Duration playerChunkUnloadDelay = Duration.parse("0t");
@Override
public void initialise() {
RegionizedPlayerChunkLoader.setUnloadDelay(this.playerChunkUnloadDelay.getTimeTicks());
}
}
@Serializable(

View File

@@ -16,8 +16,7 @@ public final class CoordinateUtils {
}
public static long getChunkKey(final Entity entity) {
final ChunkPos pos = entity.chunkPosition();
return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL);
return ((Mth.lfloor(entity.getZ()) >> 4) << 32) | ((Mth.lfloor(entity.getX()) >> 4) & 0xFFFFFFFFL);
}
public static long getChunkKey(final ChunkPos pos) {

View File

@@ -607,22 +607,6 @@ abstract class ServerLevelMixin extends Level implements ChunkSystemServerLevel,
this.moonrise$getEntityLookup().addWorldGenChunkEntities(stream.toList(), null); // TODO
}
/**
* @reason Not needed in new chunk system, also avoid accessing old entity manager
* @author Spottedleaf
*/
@Redirect(
method = {
"method_72080",
"lambda$waitForChunkAndEntities$21"
},
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;processPendingLoads()V"
)
)
private void redirectWaitForChunks(final PersistentEntitySectionManager<Entity> instance) {}
/**
* @reason Level close now handles this
* @author Spottedleaf

View File

@@ -15,8 +15,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayer.class)
abstract class ServerPlayerMixin extends Player implements ChunkSystemServerPlayer {
public ServerPlayerMixin(final Level p_250508_, final GameProfile p_252153_) {
super(p_250508_, p_252153_);
public ServerPlayerMixin(Level level, BlockPos blockPos, float f, GameProfile gameProfile) {
super(level, blockPos, f, gameProfile);
}
@Unique

View File

@@ -29,7 +29,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
@Mixin(TicketStorage.class)
@@ -194,8 +193,8 @@ abstract class TicketStorageMixin extends SavedData implements ChunkSystemTicket
* @author Spottedleaf
*/
@Overwrite
public void purgeStaleTickets(final ChunkMap chunkMap) {
((ChunkSystemServerLevel)chunkMap.level).moonrise$getChunkTaskScheduler().chunkHolderManager.tick();
public void purgeStaleTickets() {
((ChunkSystemServerLevel)this.chunkMap.level).moonrise$getChunkTaskScheduler().chunkHolderManager.tick();
this.setDirty();
}
@@ -209,11 +208,11 @@ abstract class TicketStorageMixin extends SavedData implements ChunkSystemTicket
method = "deactivateTicketsOnClosing",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/TicketStorage;removeTicketIf(Ljava/util/function/BiPredicate;Lit/unimi/dsi/fastutil/longs/Long2ObjectOpenHashMap;)V"
target = "Lnet/minecraft/world/level/TicketStorage;removeTicketIf(Ljava/util/function/Predicate;Lit/unimi/dsi/fastutil/longs/Long2ObjectOpenHashMap;)V"
)
)
private void avoidRemovingTicketsOnShutdown(final TicketStorage instance,
final BiPredicate<Long, Ticket> predicate,
final Predicate<Ticket> predicate,
final Long2ObjectOpenHashMap<List<Ticket>> tickets) {}
/**
@@ -221,7 +220,7 @@ abstract class TicketStorageMixin extends SavedData implements ChunkSystemTicket
* @author Spottedleaf
*/
@Overwrite
public void removeTicketIf(final BiPredicate<Long, Ticket> predicate, final Long2ObjectOpenHashMap<List<Ticket>> into) {
public void removeTicketIf(final Predicate<Ticket> predicate, final Long2ObjectOpenHashMap<List<Ticket>> into) {
throw new UnsupportedOperationException();
}

View File

@@ -3,10 +3,7 @@ package ca.spottedleaf.moonrise.mixin.chunk_system;
import ca.spottedleaf.moonrise.common.PlatformHooks;
import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType;
import net.minecraft.server.level.TicketType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -17,11 +14,6 @@ import java.util.concurrent.atomic.AtomicLong;
@Mixin(TicketType.class)
abstract class TicketTypeMixin<T> implements ChunkSystemTicketType<T> {
@Final
@Shadow
@Mutable
private long timeout;
@Unique
private static AtomicLong ID_GENERATOR;
@@ -74,9 +66,4 @@ abstract class TicketTypeMixin<T> implements ChunkSystemTicketType<T> {
return this.counterTypes = PlatformHooks.get().getCounterTypesUncached((TicketType)(Object)this);
}
@Override
public final void moonrise$setTimeout(final long to) {
this.timeout = to;
}
}

View File

@@ -1,25 +0,0 @@
package ca.spottedleaf.moonrise.mixin.chunk_system;
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer;
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.waypoints.Waypoint;
import net.minecraft.world.waypoints.WaypointTransmitter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@Mixin(WaypointTransmitter.class)
interface WaypointTransmitterMixin extends Waypoint {
/**
* @reason Redirect to the new player chunk loader, as the Vanilla chunk tracker is set to empty on Moonrise
* @author Spottedleaf
*/
@Overwrite
public static boolean isChunkVisible(final ChunkPos pos, final ServerPlayer player) {
final RegionizedPlayerChunkLoader.PlayerChunkLoaderData playerChunkLoader = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
return playerChunkLoader != null && playerChunkLoader.getSentChunksRaw().contains(CoordinateUtils.getChunkKey(pos));
}
}

View File

@@ -59,7 +59,7 @@ interface EntityGetterMixin {
continue;
}
if ((entity == null && otherEntity.canBeCollidedWith(entity)) || (entity != null && entity.canCollideWith(otherEntity))) {
if ((entity == null && otherEntity.canBeCollidedWith()) || (entity != null && entity.canCollideWith(otherEntity))) {
ret.add(Shapes.create(otherEntity.getBoundingBox()));
}
}

View File

@@ -1,13 +1,10 @@
package ca.spottedleaf.moonrise.mixin.serverlist;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.client.multiplayer.resolver.ServerAddress;
import net.minecraft.client.multiplayer.resolver.ServerAddressResolver;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
@Mixin(ServerAddressResolver.class)
@@ -23,18 +20,19 @@ interface ServerAddressResolverMixin {
"lambda$static$0"
},
at = @At(
value = "NEW",
target = "(Ljava/net/InetAddress;I)Ljava/net/InetSocketAddress;"
value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"
)
)
private static InetSocketAddress eliminateRDNS(InetAddress addr, final int port,
@Local(ordinal = 0, argsOnly = true) final ServerAddress serverAddress) throws UnknownHostException {
final byte[] address = addr.getAddress();
private static InetAddress eliminateRDNS(final String name) throws UnknownHostException {
final InetAddress ret = InetAddress.getByName(name);
final byte[] address = ret.getAddress();
if (address != null) {
// pass name to prevent rDNS
addr = InetAddress.getByAddress(serverAddress.getHost(), address);
return InetAddress.getByAddress(name, address);
}
return new InetSocketAddress(addr, port);
return ret;
}
}

View File

@@ -15,7 +15,7 @@ public final class ChunkSystemConverters {
private static final int DEFAULT_ENTITY_CHUNK_DATA_VERSION = -1;
private static int getCurrentVersion() {
return SharedConstants.getCurrentVersion().dataVersion().version();
return SharedConstants.getCurrentVersion().getDataVersion().getVersion();
}
private static int getDataVersion(final CompoundTag data, final int dfl) {

View File

@@ -3,7 +3,6 @@ package ca.spottedleaf.moonrise.patches.chunk_system.entity;
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.animal.HappyGhast;
import net.minecraft.world.entity.monster.Shulker;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
@@ -14,7 +13,7 @@ public interface ChunkSystemEntity {
// for mods to override
public default boolean moonrise$isHardCollidingUncached() {
return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || this instanceof HappyGhast || ((Entity)this).canBeCollidedWith(null);
return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || ((Entity)this).canBeCollidedWith();
}
public FullChunkStatus moonrise$getChunkStatus();

View File

@@ -1143,7 +1143,7 @@ public final class MoonriseRegionFileIO {
LOGGER.error("Failed to decompress chunk data for task: " + this.toString(), thr);
}
if (throwable == null && compoundTag == null) {
if (compoundTag == null) {
// need to re-try from the start
this.scheduleReadIO();
return;

View File

@@ -5,7 +5,6 @@ import ca.spottedleaf.moonrise.common.list.EntityList;
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity;
import com.google.common.collect.ImmutableList;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import net.minecraft.nbt.CompoundTag;
@@ -15,7 +14,6 @@ import net.minecraft.nbt.Tag;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
@@ -23,14 +21,9 @@ import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.storage.EntityStorage;
import net.minecraft.world.level.entity.Visibility;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.TagValueOutput;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.phys.AABB;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -39,8 +32,6 @@ import java.util.function.Predicate;
public final class ChunkEntitySlices {
private static final Logger LOGGER = LogUtils.getLogger();
public final int minSection;
public final int maxSection;
public final int chunkX;
@@ -83,12 +74,9 @@ public final class ChunkEntitySlices {
this.chunkData = chunkData;
}
public static List<Entity> readEntities(final ServerLevel world, final ChunkPos pos, final CompoundTag compoundTag) {
try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(pos), LOGGER)) {
ValueInput valueinput = TagValueInput.create(scopedCollector, world.registryAccess(), compoundTag);
public static List<Entity> readEntities(final ServerLevel world, final CompoundTag compoundTag) {
// TODO check this and below on update for format changes
return EntityType.loadEntitiesRecursive(valueinput.childrenListOrEmpty("Entities"), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList());
}
return EntityType.loadEntitiesRecursive(compoundTag.getListOrEmpty("Entities"), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList());
}
// Paper start - rewrite chunk system
@@ -116,22 +104,12 @@ public final class ChunkEntitySlices {
}
final ListTag entitiesTag = new ListTag();
try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(chunkPos), LOGGER)) {
for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) {
final TagValueOutput savedEntity = TagValueOutput.createWithContext(
scopedCollector.forChild(entity.problemPath()), entity.registryAccess()
);
try {
if (entity.save(savedEntity)) {
entitiesTag.add(savedEntity.buildResult());
}
} catch (final Exception ex) {
LOGGER.error("Entity type " + entity.getType() + " failed to serialize", ex);
CompoundTag compoundTag = new CompoundTag();
if (entity.save(compoundTag)) {
entitiesTag.add(compoundTag);
}
}
}
final CompoundTag ret = NbtUtils.addCurrentDataVersion(new CompoundTag());
ret.put("Entities", entitiesTag);
ret.store("Position", ChunkPos.CODEC, chunkPos);

View File

@@ -45,7 +45,8 @@ public final class ClientEntityLookup extends EntityLookup {
final boolean ticking = this.tickingChunks.contains(CoordinateUtils.getChunkKey(chunkX, chunkZ));
final ChunkEntitySlices ret = new ChunkEntitySlices(
this.world, chunkX, chunkZ, ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null,
this.world, chunkX, chunkZ,
ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null,
WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)
);

View File

@@ -7,14 +7,9 @@ import ca.spottedleaf.moonrise.common.util.TickThread;
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.EntityLookup;
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager;
import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.TicketType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.level.entity.LevelCallback;
public final class ServerEntityLookup extends EntityLookup {
@@ -24,13 +19,6 @@ public final class ServerEntityLookup extends EntityLookup {
private final ServerLevel serverWorld;
public final ReferenceList<Entity> trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker
// Vanilla does not increment ticket timeouts if the chunk is progressing in generation. They made this change in 1.21.6 so that the ender pearl
// ticket does not expire if the chunk fails to generate before the timeout expires. Rather than blindly adjusting the entire system behavior
// to fix this small issue, we instead add non-expirable tickets here to keep ender pearls ticking. This is how the original feature should have
// been implemented, but I don't think Vanilla has proper entity add/remove hooks like we do. Fixes MC-297591
private static final TicketType ENDER_PEARL_TICKER = ChunkSystemTicketType.create("chunk_system:ender_pearl_ticker", null);
private final Long2IntOpenHashMap enderPearlChunkCount = new Long2IntOpenHashMap();
public ServerEntityLookup(final ServerLevel world, final LevelCallback<Entity> worldCallback) {
super(world, worldCallback);
this.serverWorld = world;
@@ -75,10 +63,6 @@ public final class ServerEntityLookup extends EntityLookup {
if (entity instanceof ServerPlayer player) {
((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player);
}
if (entity instanceof ThrownEnderpearl enderpearl && (oldSectionX != newSectionX || oldSectionZ != newSectionZ)) {
this.removeEnderPearl(CoordinateUtils.getChunkKey(oldSectionX, oldSectionZ));
this.addEnderPearl(CoordinateUtils.getChunkKey(newSectionX, newSectionZ));
}
PlatformHooks.get().entityMove(
entity,
CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ),
@@ -91,9 +75,6 @@ public final class ServerEntityLookup extends EntityLookup {
if (entity instanceof ServerPlayer player) {
((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().addPlayer(player);
}
if (entity instanceof ThrownEnderpearl enderpearl) {
this.addEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition()));
}
}
@Override
@@ -101,9 +82,6 @@ public final class ServerEntityLookup extends EntityLookup {
if (entity instanceof ServerPlayer player) {
((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player);
}
if (entity instanceof ThrownEnderpearl enderpearl) {
this.removeEnderPearl(CoordinateUtils.getChunkKey(enderpearl.chunkPosition()));
}
}
@Override
@@ -134,23 +112,4 @@ public final class ServerEntityLookup extends EntityLookup {
protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) {
return PlatformHooks.get().screenEntity(this.serverWorld, entity, fromDisk, event);
}
private void addEnderPearl(final long coordinate) {
final int oldCount = this.enderPearlChunkCount.addTo(coordinate, 1);
if (oldCount != 0) {
return;
}
((ChunkSystemServerLevel)this.serverWorld).moonrise$getChunkTaskScheduler().chunkHolderManager
.addTicketAtLevel(ENDER_PEARL_TICKER, coordinate, ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL, null);
}
private void removeEnderPearl(final long coordinate) {
final int oldCount = this.enderPearlChunkCount.addTo(coordinate, -1);
if (oldCount != 1) {
return;
}
this.enderPearlChunkCount.remove(coordinate);
((ChunkSystemServerLevel)this.serverWorld).moonrise$getChunkTaskScheduler().chunkHolderManager
.removeTicketAtLevel(ENDER_PEARL_TICKER, coordinate, ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL, null);
}
}

View File

@@ -119,7 +119,7 @@ public final class PoiChunk {
final CompoundTag sections = new CompoundTag();
ret.put("Sections", sections);
ret.putInt("DataVersion", SharedConstants.getCurrentVersion().dataVersion().version());
ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion());
final ServerLevel world = this.world;
final int chunkX = this.chunkX;

View File

@@ -47,16 +47,12 @@ import java.util.function.Function;
public final class RegionizedPlayerChunkLoader {
public static final TicketType PLAYER_TICKET = ChunkSystemTicketType.create("chunk_system:player_ticket", Long::compareTo);
public static final TicketType PLAYER_TICKET_DELAYED = ChunkSystemTicketType.create("chunk_system:player_ticket_delayed", Long::compareTo, 1L);
public static final TicketType PLAYER_TICKET_DELAYED = ChunkSystemTicketType.create("chunk_system:player_ticket_delayed", Long::compareTo, 5L * 20L);
public static final int GENERATED_TICKET_LEVEL = ChunkHolderManager.FULL_LOADED_TICKET_LEVEL;
public static final int LOADED_TICKET_LEVEL = ChunkTaskScheduler.getTicketLevel(ChunkStatus.EMPTY);
public static final int TICK_TICKET_LEVEL = ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL;
public static void setUnloadDelay(final long ticks) {
((ChunkSystemTicketType)(Object)PLAYER_TICKET_DELAYED).moonrise$setTimeout(Math.max(1, ticks));
}
public static final class ViewDistanceHolder {
private volatile ViewDistances viewDistances;
@@ -151,7 +147,7 @@ public final class RegionizedPlayerChunkLoader {
}
public static int getAPITickViewDistance(final ServerPlayer player) {
final ServerLevel level = player.level();
final ServerLevel level = player.serverLevel();
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
if (data == null) {
return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPITickDistance();
@@ -160,7 +156,7 @@ public final class RegionizedPlayerChunkLoader {
}
public static int getAPIViewDistance(final ServerPlayer player) {
final ServerLevel level = player.level();
final ServerLevel level = player.serverLevel();
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
if (data == null) {
return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPIViewDistance();
@@ -170,7 +166,7 @@ public final class RegionizedPlayerChunkLoader {
}
public static int getAPISendViewDistance(final ServerPlayer player) {
final ServerLevel level = player.level();
final ServerLevel level = player.serverLevel();
final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader();
if (data == null) {
return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPISendViewDistance();

View File

@@ -1,6 +1,5 @@
package ca.spottedleaf.moonrise.patches.chunk_system.scheduling;
import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock;
import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable;
import ca.spottedleaf.concurrentutil.util.Priority;
@@ -83,7 +82,6 @@ public final class ChunkHolderManager {
private long currentTick;
private final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = new ArrayDeque<>();
private final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = new MultiThreadedQueue<>();
private final ObjectRBTreeSet<NewChunkHolder> autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> {
if (c1 == c2) {
return 0;
@@ -114,20 +112,20 @@ public final class ChunkHolderManager {
this.unloadQueue = new ChunkUnloadQueue(((ChunkSystemServerLevel)world).moonrise$getRegionChunkShift());
}
public boolean processTicketUpdates(final int chunkX, final int chunkZ) {
public boolean processTicketUpdates(final int posX, final int posZ) {
final int ticketShift = ThreadedTicketLevelPropagator.SECTION_SHIFT;
final int ticketMask = (1 << ticketShift) - 1;
final List<ChunkProgressionTask> scheduledTasks = new ArrayList<>();
final List<NewChunkHolder> changedFullStatus = new ArrayList<>();
final boolean ret;
final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(
((chunkX >> ticketShift) - 1) << ticketShift,
((chunkZ >> ticketShift) - 1) << ticketShift,
(((chunkX >> ticketShift) + 1) << ticketShift) | ticketMask,
(((chunkZ >> ticketShift) + 1) << ticketShift) | ticketMask
((posX >> ticketShift) - 1) << ticketShift,
((posZ >> ticketShift) - 1) << ticketShift,
(((posX >> ticketShift) + 1) << ticketShift) | ticketMask,
(((posZ >> ticketShift) + 1) << ticketShift) | ticketMask
);
try {
ret = this.processTicketUpdatesNoLock(chunkX >> ticketShift, chunkZ >> ticketShift, scheduledTasks, changedFullStatus);
ret = this.processTicketUpdatesNoLock(posX >> ticketShift, posZ >> ticketShift, scheduledTasks, changedFullStatus);
} finally {
this.ticketLockArea.unlock(ticketLock);
}
@@ -807,9 +805,6 @@ public final class ChunkHolderManager {
return removeDelay <= 0L;
};
final List<ChunkProgressionTask> scheduledTasks = new ArrayList<>();
final List<NewChunkHolder> changedFullStatus = new ArrayList<>();
for (final PrimitiveIterator.OfLong iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) {
final long sectionKey = iterator.nextLong();
@@ -818,16 +813,9 @@ public final class ChunkHolderManager {
continue;
}
final int lowerChunkX = CoordinateUtils.getChunkX(sectionKey) << sectionShift;
final int lowerChunkZ = CoordinateUtils.getChunkZ(sectionKey) << sectionShift;
final int ticketShift = ThreadedTicketLevelPropagator.SECTION_SHIFT;
final int ticketMask = (1 << ticketShift) - 1;
final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(
((lowerChunkX >> ticketShift) - 1) << ticketShift,
((lowerChunkZ >> ticketShift) - 1) << ticketShift,
(((lowerChunkX >> ticketShift) + 1) << ticketShift) | ticketMask,
(((lowerChunkZ >> ticketShift) + 1) << ticketShift) | ticketMask
CoordinateUtils.getChunkX(sectionKey) << sectionShift,
CoordinateUtils.getChunkZ(sectionKey) << sectionShift
);
try {
@@ -874,23 +862,9 @@ public final class ChunkHolderManager {
if (chunkToExpireCount.isEmpty()) {
this.sectionToChunkToExpireCount.remove(sectionKey);
}
// In order to prevent a race condition where an off-thread invokes processTicketUpdates(), we need to process ticket updates here
// so that we catch any additions to the changed full status list. If an off-thread were to process tickets here, it would not be guaranteed
// that it would be added to the full changed status set by the end of the call - possibly allowing ticket level decreases to be processed
// outside of this call, which is not an intended or expected of this chunk system.
this.processTicketUpdatesNoLock(lowerChunkX >> ThreadedTicketLevelPropagator.SECTION_SHIFT, lowerChunkZ >> ThreadedTicketLevelPropagator.SECTION_SHIFT, scheduledTasks, changedFullStatus);
} finally {
this.ticketLockArea.unlock(ticketLock);
}
this.addChangedStatuses(changedFullStatus);
changedFullStatus.clear(); // clear for next loop iteration
for (int i = 0, len = scheduledTasks.size(); i < len; ++i) {
scheduledTasks.get(i).schedule();
}
scheduledTasks.clear(); // clear for next loop iteration
}
this.processTicketUpdates();
@@ -1117,9 +1091,14 @@ public final class ChunkHolderManager {
return;
}
if (!TickThread.isTickThread()) {
// These will be handled on the next ServerChunkCache$MainThreadExecutor#pollTask, as it runs the distance manager update
// which will invoke processTicketUpdates
this.offThreadPendingFullLoadUpdate.addAll(changedFullStatus);
this.taskScheduler.scheduleChunkTask(() -> {
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
pendingFullLoadUpdate.add(changedFullStatus.get(i));
}
ChunkHolderManager.this.processPendingFullUpdate();
}, Priority.HIGHEST);
} else {
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
@@ -1400,20 +1379,36 @@ public final class ChunkHolderManager {
}
public boolean processTicketUpdates() {
return this.processTicketUpdates(true, null);
}
private static final ThreadLocal<List<ChunkProgressionTask>> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>();
static List<ChunkProgressionTask> getCurrentTicketUpdateScheduling() {
return CURRENT_TICKET_UPDATE_SCHEDULING.get();
}
private boolean processTicketUpdates(final boolean processFullUpdates, List<ChunkProgressionTask> scheduledTasks) {
if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager");
}
final boolean isTickThread = TickThread.isTickThread();
if (!PlatformHooks.get().allowAsyncTicketUpdates() && isTickThread) {
if (!PlatformHooks.get().allowAsyncTicketUpdates() && !TickThread.isTickThread()) {
TickThread.ensureTickThread("Cannot asynchronously process ticket updates");
}
List<NewChunkHolder> changedFullStatus = null;
final boolean isTickThread = TickThread.isTickThread();
boolean ret = false;
final boolean canProcessFullUpdates = processFullUpdates & isTickThread;
final boolean canProcessScheduling = scheduledTasks == null;
if (this.ticketLevelPropagator.hasPendingUpdates()) {
final List<ChunkProgressionTask> scheduledTasks = new ArrayList<>();
final List<NewChunkHolder> changedFullStatus = new ArrayList<>();
if (scheduledTasks == null) {
scheduledTasks = new ArrayList<>();
}
changedFullStatus = new ArrayList<>();
this.blockTicketUpdates();
try {
@@ -1424,42 +1419,27 @@ public final class ChunkHolderManager {
} finally {
this.unblockTicketUpdates(Boolean.FALSE);
}
}
if (changedFullStatus != null) {
this.addChangedStatuses(changedFullStatus);
}
if (canProcessScheduling && scheduledTasks != null) {
for (int i = 0, len = scheduledTasks.size(); i < len; ++i) {
scheduledTasks.get(i).schedule();
}
}
if (isTickThread) {
if (canProcessFullUpdates) {
ret |= this.processPendingFullUpdate();
}
return ret;
}
private static final ThreadLocal<List<ChunkProgressionTask>> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>();
static List<ChunkProgressionTask> getCurrentTicketUpdateScheduling() {
return CURRENT_TICKET_UPDATE_SCHEDULING.get();
}
// only call on tick thread
private void processOffThreadFullUpdates() {
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = this.offThreadPendingFullLoadUpdate;
NewChunkHolder toUpdate;
while ((toUpdate = offThreadPendingFullLoadUpdate.poll()) != null) {
pendingFullLoadUpdate.add(toUpdate);
}
}
// only call on tick thread
private boolean processPendingFullUpdate() {
this.processOffThreadFullUpdates();
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
boolean ret = false;

View File

@@ -117,11 +117,9 @@ public final class NewChunkHolder {
if (!transientChunk) {
if (entityChunk != null) {
final ChunkPos pos = new ChunkPos(this.chunkX, this.chunkZ);
final List<Entity> entities = ChunkEntitySlices.readEntities(this.world, entityChunk);
final List<Entity> entities = ChunkEntitySlices.readEntities(this.world, pos, entityChunk);
((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, pos);
((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ));
}
}

View File

@@ -30,5 +30,4 @@ public interface ChunkSystemTicketType<T> {
public long[] moonrise$getCounterTypes();
public void moonrise$setTimeout(final long to);
}

View File

@@ -2091,7 +2091,7 @@ public final class CollisionUtil {
continue;
}
if ((entity == null && otherEntity.canBeCollidedWith(entity)) || (entity != null && entity.canCollideWith(otherEntity))) {
if ((entity == null && otherEntity.canBeCollidedWith()) || (entity != null && entity.canCollideWith(otherEntity))) {
if (checkOnly) {
return true;
} else {

View File

@@ -177,7 +177,7 @@ accessible method net/minecraft/server/network/PlayerChunkSender sendChunk (Lnet
# ChunkStatusTasks
accessible method net/minecraft/world/level/chunk/status/ChunkStatusTasks postLoadProtoChunk (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/storage/ValueInput$ValueInputList;)V
accessible method net/minecraft/world/level/chunk/status/ChunkStatusTasks postLoadProtoChunk (Lnet/minecraft/server/level/ServerLevel;Ljava/util/List;)V
accessible method net/minecraft/world/level/chunk/status/ChunkStatusTasks light (Lnet/minecraft/world/level/chunk/status/WorldGenContext;Lnet/minecraft/world/level/chunk/status/ChunkStep;Lnet/minecraft/util/StaticCache2D;Lnet/minecraft/world/level/chunk/ChunkAccess;)Ljava/util/concurrent/CompletableFuture;

View File

@@ -54,7 +54,6 @@
"chunk_system.TicketMixin",
"chunk_system.TicketStorageMixin",
"chunk_system.TicketTypeMixin",
"chunk_system.WaypointTransmitterMixin",
"chunk_tick_iteration.ChunkMapMixin",
"chunk_tick_iteration.DistanceManagerMixin",
"chunk_tick_iteration.ServerChunkCacheMixin",