From 7cce46144a39911b197734ca36c70b89b0ad4a3d Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Wed, 17 Jul 2024 03:20:22 +0800 Subject: [PATCH] feat: force load enclosure --- build.gradle | 2 +- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../github/zly2006/enclosure/EnclosureArea.kt | 10 +++++ .../github/zly2006/enclosure/EnclosureList.kt | 28 ++++++++++-- .../zly2006/enclosure/command/BuilderScope.kt | 4 +- .../enclosure/command/ForceLoadSubcommand.kt | 45 ++++++++++++++++--- src/main/resources/enclosure.accesswidener | 4 ++ 8 files changed, 83 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index b196b2c..795ce8f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "fabric-loom" version "1.6-SNAPSHOT" apply false + id "fabric-loom" version "1.7-SNAPSHOT" apply false id "maven-publish" id "org.ajoberstar.grgit" version "5.2.2" id "org.jetbrains.kotlin.jvm" version "2.0.0" diff --git a/gradle.properties b/gradle.properties index 44e7c68..66f8c8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,8 +12,8 @@ rei_version = 9.1.550 # check these on https://fabricmc.net/develop minecraft_version=1.21 -yarn_mappings=1.21+build.1 +yarn_mappings=1.21+build.9 loader_version=0.15.11 # Fabric API -fabric_version=0.100.0+1.21 +fabric_version=0.100.7+1.21 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 509c4a2..171d876 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt index 2e1a34d..b59ce29 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt @@ -16,6 +16,7 @@ import net.minecraft.nbt.NbtList import net.minecraft.registry.RegistryWrapper import net.minecraft.server.command.ServerCommandSource import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.server.world.ChunkTicketType import net.minecraft.server.world.ServerWorld import net.minecraft.text.ClickEvent import net.minecraft.text.MutableText @@ -422,6 +423,15 @@ open class EnclosureArea : PersistentState, EnclosureView { final override fun markDirty() { ServerMain.getAllEnclosures(world).markDirty() + if (ticket != null) { + toBlockBox().streamChunkPos().forEach { + val level = world.chunkManager.ticketManager.simulationDistanceTracker.getLevel(it.toLong()) + if (level > ticket!!.level) { + world.chunkManager.addTicket(ChunkTicketType.FORCED, it, ticket!!.level, it) + } + } + } + super.markDirty() } fun setTeleportPos(teleportPos: Vec3d?, yaw: Float, pitch: Float) { diff --git a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt index 938038b..d5ee213 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt @@ -3,12 +3,15 @@ package com.github.zly2006.enclosure import com.github.zly2006.enclosure.ServerMain.enclosures import com.github.zly2006.enclosure.ServerMain.getAllEnclosures import com.github.zly2006.enclosure.access.ChunkAccess +import com.github.zly2006.enclosure.utils.Serializable2Text +import com.github.zly2006.enclosure.utils.Serializable2Text.SerializationSettings.NameHover import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtList import net.minecraft.nbt.NbtString import net.minecraft.registry.RegistryWrapper import net.minecraft.server.world.ChunkTicketType import net.minecraft.server.world.ServerWorld +import net.minecraft.text.Text import net.minecraft.util.math.BlockPos import net.minecraft.world.PersistentState import net.minecraft.world.chunk.ChunkStatus @@ -111,12 +114,29 @@ class EnclosureList(world: ServerWorld, private val isRoot: Boolean) : Persisten if (area.ticket != null) { area.ticket!!.remainingTicks-- if (area.ticket!!.remainingTicks <= 0) { - area.toBlockBox().streamChunkPos().forEach { - world.chunkManager.removeTicket(ChunkTicketType.FORCED, it, area.ticket!!.level, it) - } - // todo: message area.ticket = null + removeTicket(area, world) + world.server.playerManager.broadcast( + Text.literal("Force loading for ").append(area.serialize(NameHover, null)).append(" expired."), false + ) + // todo: message + } + area.markDirty() + } + } + } + + private fun removeTicket(area: EnclosureArea, world: ServerWorld) { + area.toBlockBox().streamChunkPos().forEach { + val chunk = world.getChunkAsView(it.x, it.z) + if (chunk is ChunkAccess) { + val targetLevel = chunk.cache.mapNotNull { it.ticket }.minOfOrNull { it.level } + world.chunkManager.ticketManager.ticketsByPosition.remove(it.toLong()) + if (targetLevel != null) { + world.chunkManager.addTicket(ChunkTicketType.FORCED, it, targetLevel, it) } + } else { + world.chunkManager.removeTicket(ChunkTicketType.FORCED, it, area.ticket!!.level, it) } } } diff --git a/src/main/kotlin/com/github/zly2006/enclosure/command/BuilderScope.kt b/src/main/kotlin/com/github/zly2006/enclosure/command/BuilderScope.kt index f29885d..d701400 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/command/BuilderScope.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/command/BuilderScope.kt @@ -46,9 +46,9 @@ class BuilderScope(var parent: T) { error(e.text, it) } catch (e: CommandSyntaxException) { throw e - } catch (e: Exception) { + } catch (e: Throwable) { LOGGER.error("Error while executing command: " + it.input, e) - error(TrT.of("enclosure.message.error").append(e.message), it) + error(TrT.of("enclosure.message.error").append("${e.javaClass.simpleName}: ${e.message}"), it) } } } diff --git a/src/main/kotlin/com/github/zly2006/enclosure/command/ForceLoadSubcommand.kt b/src/main/kotlin/com/github/zly2006/enclosure/command/ForceLoadSubcommand.kt index 68f882b..9b13c01 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/command/ForceLoadSubcommand.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/command/ForceLoadSubcommand.kt @@ -20,17 +20,37 @@ fun BuilderScope<*>.registerForceLoad() { ) area.ticket = ticket area.markDirty() - source.sendMessage( - Text.literal("Force loading ") - .append(area.serialize(Name, null)) - .append(" with level $level") + source.sendFeedback( + { + Text.literal("Force loading ") + .append(area.serialize(Name, null)) + .append(" with level $level") + }, true ) } + fun cancelForceLoad(source: ServerCommandSource, area: Enclosure) { + if (area.ticket != null) { + area.ticket!!.remainingTicks = 0 + area.markDirty() + source.sendFeedback( + { + Text.literal("Force loading for ") + .append(area.serialize(Name, null)) + .append(" canceled") + }, + true + ) + } + else { + source.sendError(Text.literal("No force loading tickets for ").append(area.serialize(Name, null))) + } + } + literal("force-load") { argument(landArgument()) { + permission("enclosure.command.force_load") literal("blocks") { - permission("enclosure.command.force_load") val level = ChunkLevels.getLevelFromType(ChunkLevelType.BLOCK_TICKING) executes { val maxTime = Options.get(source, "enclosure.load.max_time", 21600) { it.toInt() } @@ -42,7 +62,6 @@ fun BuilderScope<*>.registerForceLoad() { } } literal("entities") { - permission("enclosure.command.force_load") val level = ChunkLevels.getLevelFromType(ChunkLevelType.ENTITY_TICKING) executes { val maxTime = Options.get(source, "enclosure.load.max_time", 21600) { it.toInt() } @@ -53,6 +72,20 @@ fun BuilderScope<*>.registerForceLoad() { forceLoad(source, land, maxTime * 20, level) } } + literal("cancel") { + executes { + val land = getEnclosure(this) + if (land !is Enclosure) { + error(Text.literal("Only enclosure can be force loaded"), this) + } + cancelForceLoad(source, land) + } + } + } + literal("list") { + executes { + TODO() + } } } } diff --git a/src/main/resources/enclosure.accesswidener b/src/main/resources/enclosure.accesswidener index 213d524..9a132b2 100644 --- a/src/main/resources/enclosure.accesswidener +++ b/src/main/resources/enclosure.accesswidener @@ -16,3 +16,7 @@ accessible field net/minecraft/server/world/ServerChunkLoadingManager entityTrac accessible field net/minecraft/server/world/ServerChunkLoadingManager$EntityTracker entry Lnet/minecraft/server/network/EntityTrackerEntry; accessible field net/minecraft/inventory/DoubleInventory first Lnet/minecraft/inventory/Inventory; accessible field net/minecraft/inventory/DoubleInventory second Lnet/minecraft/inventory/Inventory; +accessible field net/minecraft/server/world/ChunkTicketManager simulationDistanceTracker Lnet/minecraft/world/SimulationDistanceLevelPropagator; +accessible field net/minecraft/server/world/ServerChunkManager ticketManager Lnet/minecraft/server/world/ChunkTicketManager; +accessible method net/minecraft/world/SimulationDistanceLevelPropagator getLevel (J)I +accessible field net/minecraft/server/world/ChunkTicketManager ticketsByPosition Lit/unimi/dsi/fastutil/longs/Long2ObjectOpenHashMap;