9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00

Remove fast resume, mojang added it

This commit is contained in:
violetc
2025-06-06 02:24:57 +08:00
parent f1cc3ef9af
commit 73bd42af2e
38 changed files with 1 additions and 254 deletions

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Wed, 5 Feb 2025 23:42:44 +0800
Subject: [PATCH] Fast resume
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index f473999938840562b1007a789600342e5796a123..7e20b6469ef06c0338b5298d36b3a1ba1c52e897 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -656,6 +656,49 @@ public final class ChunkHolderManager {
}
}
+ // Leaves start - add custom ticket
+ public <T> void addTicketAtLevelCustom(final Ticket ticket, final long chunk, final boolean lock) {
+ final long removeDelay = ticket.moonrise$getRemoveDelay();
+
+ final int chunkX = CoordinateUtils.getChunkX(chunk);
+ final int chunkZ = CoordinateUtils.getChunkZ(chunk);
+
+ final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null;
+ try {
+ final SortedArraySet<Ticket> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (final long keyInMap) -> SortedArraySet.create(4));
+
+ final int levelBefore = getTicketLevelAt(ticketsAtChunk);
+ final Ticket current = ((ChunkSystemSortedArraySet<Ticket>)ticketsAtChunk).moonrise$replace(ticket);
+ final int levelAfter = getTicketLevelAt(ticketsAtChunk);
+
+ if (current != ticket) {
+ final long oldRemoveDelay = ((ChunkSystemTicket<?>) current).moonrise$getRemoveDelay();
+ if (removeDelay != oldRemoveDelay) {
+ if (oldRemoveDelay != NO_TIMEOUT_MARKER && removeDelay == NO_TIMEOUT_MARKER) {
+ this.removeExpireCount(chunkX, chunkZ);
+ } else if (oldRemoveDelay == NO_TIMEOUT_MARKER) {
+ // since old != new, we have that NO_TIMEOUT_MARKER != new
+ this.addExpireCount(chunkX, chunkZ);
+ }
+ }
+ } else {
+ if (removeDelay != NO_TIMEOUT_MARKER) {
+ this.addExpireCount(chunkX, chunkZ);
+ }
+ }
+
+ if (levelBefore != levelAfter) {
+ this.updateTicketLevel(chunk, levelAfter);
+ }
+
+ } finally {
+ if (ticketLock != null) {
+ this.ticketLockArea.unlock(ticketLock);
+ }
+ }
+ }
+ // Leaves end - add custom ticket
+
private void removeTicketCounter(final TicketType type, final long pos) {
final long[] counterTypes = ((ChunkSystemTicketType<?>)(Object)type).moonrise$getCounterTypes();
if (counterTypes.length == 0) {
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index f1681577f27a618338cae1634094e728c98fc3ff..6bc08a61a51b19e8f5670b0c54a3faeeab16bbc4 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -742,6 +742,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getBotList().loadResume(); // Leaves - load resident bot
+ org.leavesmc.leaves.util.TicketHelper.tryToLoadTickets(); // Leaves - load ticket
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
this.server.spark.enableAfterPlugins(this.server); // Paper - spark
@@ -982,6 +983,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit end
public void stopServer() {
+ org.leavesmc.leaves.util.TicketHelper.tryToSaveTickets(); // Leaves - save ticket
// CraftBukkit start - prevent double stopping on multiple threads
synchronized(this.stopLock) {
if (this.hasStopped) return;

View File

@@ -566,9 +566,6 @@ public final class LeavesConfig {
} }
} }
@GlobalConfig("fast-resume")
public boolean fastResume = false;
public ForcePeacefulModeSwitchConfig peacefulModeSwitch = new ForcePeacefulModeSwitchConfig(); public ForcePeacefulModeSwitchConfig peacefulModeSwitch = new ForcePeacefulModeSwitchConfig();
@GlobalConfigCategory("force-peaceful-mode-switch") @GlobalConfigCategory("force-peaceful-mode-switch")
@@ -635,6 +632,7 @@ public final class LeavesConfig {
@RemovedConfig(name = "disable-moved-wrongly-threshold", category = "modify") @RemovedConfig(name = "disable-moved-wrongly-threshold", category = "modify")
@RemovedConfig(name = "ignore-lc", category = "modify") @RemovedConfig(name = "ignore-lc", category = "modify")
@RemovedConfig(name = "fix-fortress-mob-spawn", category = {"modify", "minecraft-old"}) @RemovedConfig(name = "fix-fortress-mob-spawn", category = {"modify", "minecraft-old"})
@RemovedConfig(name = "fast-resume", category = "modify")
private final boolean removed = false; private final boolean removed = false;
} }

View File

@@ -1,171 +0,0 @@
package org.leavesmc.leaves.util;
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.Ticket;
import net.minecraft.server.level.TicketType;
import net.minecraft.util.SortedArraySet;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.storage.LevelResource;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.LeavesLogger;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Set;
@SuppressWarnings("rawtypes")
public class TicketHelper {
private static final Set<TicketType> NEED_SAVED = Set.of(TicketType.PORTAL, RegionizedPlayerChunkLoader.PLAYER_TICKET);
public static void tryToLoadTickets() {
if (!LeavesConfig.modify.fastResume) {
return;
}
File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("chunk_tickets.leaves.json").toFile();
if (file.isFile()) {
try (BufferedReader bfr = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
JsonObject json = new Gson().fromJson(bfr, JsonObject.class);
loadSavedChunkTickets(json);
if (!file.delete()) {
throw new IOException();
}
} catch (IOException e) {
LeavesLogger.LOGGER.severe("Failed to load saved chunk tickets file", e);
}
}
}
public static void tryToSaveTickets() {
if (!LeavesConfig.modify.fastResume) {
return;
}
File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("chunk_tickets.leaves.json").toFile();
try (BufferedWriter bfw = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
bfw.write(new Gson().toJson(getSavedChunkTickets()));
} catch (IOException e) {
LeavesLogger.LOGGER.severe("Failed to save chunk tickets file", e);
}
}
public static void loadSavedChunkTickets(JsonObject json) {
MinecraftServer server = MinecraftServer.getServer();
for (String worldKey : json.keySet()) {
ResourceLocation dimensionKey = ResourceLocation.tryParse(worldKey);
if (dimensionKey == null) {
continue;
}
ServerLevel level = server.getLevel(ResourceKey.create(Registries.DIMENSION, dimensionKey));
if (level == null) {
continue;
}
DistanceManager chunkDistanceManager = level.getChunkSource().chunkMap.distanceManager;
for (JsonElement chunkElement : json.get(worldKey).getAsJsonArray()) {
JsonObject chunkJson = (JsonObject) chunkElement;
long chunkKey = chunkJson.get("key").getAsLong();
for (JsonElement ticketElement : chunkJson.get("tickets").getAsJsonArray()) {
Ticket<?> ticket = tickFormJson((JsonObject) ticketElement);
chunkDistanceManager.moonrise$getChunkHolderManager().addTicketAtLevelCustom(ticket, chunkKey, true);
}
}
}
}
public static JsonObject getSavedChunkTickets() {
JsonObject json = new JsonObject();
for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) {
JsonArray levelArray = new JsonArray();
DistanceManager chunkDistanceManager = level.getChunkSource().chunkMap.distanceManager;
for (Long2ObjectMap.Entry<SortedArraySet<Ticket>> chunkTickets : chunkDistanceManager.moonrise$getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) {
long chunkKey = chunkTickets.getLongKey();
JsonArray ticketArray = new JsonArray();
SortedArraySet<Ticket> tickets = chunkTickets.getValue();
for (Ticket<?> ticket : tickets) {
if (!NEED_SAVED.contains(ticket.getType())) {
continue;
}
ticketArray.add(ticketToJson(ticket));
}
if (!ticketArray.isEmpty()) {
JsonObject chunkJson = new JsonObject();
chunkJson.addProperty("key", chunkKey);
chunkJson.add("tickets", ticketArray);
levelArray.add(chunkJson);
}
}
if (!levelArray.isEmpty()) {
json.add(level.dimension().location().toString(), levelArray);
}
}
return json;
}
private static JsonObject ticketToJson(Ticket<?> ticket) {
JsonObject json = new JsonObject();
json.addProperty("type", ticket.getType().toString());
json.addProperty("ticketLevel", ticket.getTicketLevel());
json.addProperty("removeDelay", ticket.moonrise$getRemoveDelay());
switch (ticket.getIdentifier()) {
case BlockPos pos -> json.addProperty("key", pos.asLong());
case ChunkPos pos -> json.addProperty("key", pos.toLong());
case Long l -> json.addProperty("key", l);
default -> {
}
}
return json;
}
private static <T> Ticket<T> tickFormJson(JsonObject json) {
TicketType ticketType = null;
Object key = null;
switch (json.get("type").getAsString()) {
case "portal" -> {
ticketType = TicketType.PORTAL;
key = BlockPos.of(json.get("key").getAsLong());
}
case "chunk_system:player_ticket" -> {
ticketType = RegionizedPlayerChunkLoader.PLAYER_TICKET;
key = json.get("key").getAsLong();
}
}
if (ticketType == null) {
throw new IllegalArgumentException("Cant convert " + json.get("type").getAsString() + ", report it ???");
}
int ticketLevel = json.get("ticketLevel").getAsInt();
long removeDelay = json.get("removeDelay").getAsLong();
Ticket<T> ticket = new Ticket<>(ticketType, ticketLevel, key);
ticket.moonrise$setRemoveDelay(removeDelay);
return ticket;
}
}