fabric-1.18: switch to new CHUNK_GENERATE event, simplify trigger logic greatly

This commit is contained in:
Kosma Moczek 2021-12-16 20:25:27 +01:00
parent 69f5dbd63a
commit a9c0446d00
2 changed files with 25 additions and 124 deletions

View File

@ -2,8 +2,6 @@ package org.dynmap.fabric_1_18;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
@ -20,8 +18,6 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ChunkHolder;
import net.minecraft.server.world.ServerChunkManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.collection.IdList;
@ -46,10 +42,10 @@ import org.dynmap.fabric_1_18.command.DmarkerCommand;
import org.dynmap.fabric_1_18.command.DynmapCommand;
import org.dynmap.fabric_1_18.command.DynmapExpCommand;
import org.dynmap.fabric_1_18.event.BlockEvents;
import org.dynmap.fabric_1_18.event.CustomServerChunkEvents;
import org.dynmap.fabric_1_18.event.CustomServerLifecycleEvents;
import org.dynmap.fabric_1_18.event.PlayerEvents;
import org.dynmap.fabric_1_18.mixin.BiomeEffectsAccessor;
import org.dynmap.fabric_1_18.mixin.ThreadedAnvilChunkStorageAccessor;
import org.dynmap.fabric_1_18.permissions.FilePermissions;
import org.dynmap.fabric_1_18.permissions.OpPermissions;
import org.dynmap.fabric_1_18.permissions.PermissionProvider;
@ -125,32 +121,6 @@ public class DynmapPlugin {
public static DynmapBlockState[] stateByID;
private Map<String, LongOpenHashSet> knownloadedchunks = new HashMap<String, LongOpenHashSet>();
private void addKnownChunk(FabricWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset == null) {
cset = new LongOpenHashSet();
knownloadedchunks.put(fw.getName(), cset);
}
cset.add(pos.toLong());
}
private void removeKnownChunk(FabricWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset != null) {
cset.remove(pos.toLong());
}
}
private boolean checkIfKnownChunk(FabricWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset != null) {
return cset.contains(pos.toLong());
}
return false;
}
/**
* Initialize block states (org.dynmap.blockstate.DynmapBlockState)
*/
@ -657,69 +627,25 @@ public class DynmapPlugin {
}
}
public void handleChunkLoad(ServerWorld world, WorldChunk chunk) {
public void handleChunkGenerate(ServerWorld world, Chunk chunk) {
if (!onchunkgenerate) return;
if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) {
FabricWorld fw = getWorld(world, false);
if (fw != null) {
addKnownChunk(fw, chunk.getPos());
FabricWorld fw = getWorld(world, false);
ChunkPos chunkPos = chunk.getPos();
int yMax = 0;
ChunkSection[] sections = chunk.getSectionArray();
for (int i = 0; i < sections.length; i++) {
if ((sections[i] != null) && (!sections[i].isEmpty())) {
yMax = 16 * (i + 1);
}
}
}
public void handleChunkUnload(ServerWorld world, WorldChunk chunk) {
if (!onchunkgenerate) return;
if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) {
FabricWorld fw = getWorld(world, false);
ChunkPos cp = chunk.getPos();
if (fw != null) {
if (!checkIfKnownChunk(fw, cp)) {
int ymax = 0;
ChunkSection[] sections = chunk.getSectionArray();
for (int i = 0; i < sections.length; i++) {
if ((sections[i] != null) && (!sections[i].isEmpty())) {
ymax = 16 * (i + 1);
}
}
int x = cp.x << 4;
int z = cp.z << 4;
// If not empty AND not initial scan
if (ymax > 0) {
Log.info("New generated chunk detected at " + cp + " for " + fw.getName());
mapManager.touchVolume(fw.getName(), x, 0, z, x + 15, ymax, z + 16, "chunkgenerate");
}
}
removeKnownChunk(fw, cp);
}
}
}
public void handleChunkDataSave(ServerWorld world, Chunk chunk) {
if (!onchunkgenerate) return;
if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) {
FabricWorld fw = getWorld(world, false);
ChunkPos cp = chunk.getPos();
if (fw != null) {
if (!checkIfKnownChunk(fw, cp)) {
int ymax = 0;
ChunkSection[] sections = chunk.getSectionArray();
for (int i = 0; i < sections.length; i++) {
if ((sections[i] != null) && (!sections[i].isEmpty())) {
ymax = 16 * (i + 1);
}
}
int x = cp.x << 4;
int z = cp.z << 4;
// If not empty AND not initial scan
if (ymax > 0) {
mapManager.touchVolume(fw.getName(), x, 0, z, x + 15, ymax, z + 16, "chunkgenerate");
}
addKnownChunk(fw, cp);
}
}
if (yMax > 0) {
mapManager.touchVolume(fw.getName(),
chunkPos.getStartX(), 0, chunkPos.getStartZ(),
chunkPos.getEndX(), yMax, chunkPos.getEndZ(),
"chunkgenerate");
//Log.info("New generated chunk detected at %s[%s]".formatted(fw.getName(), chunkPos.getStartPos()));
}
}
@ -754,39 +680,17 @@ public class DynmapPlugin {
onblockchange_with_id = core.isTrigger("blockupdate-with-id");
if (onblockchange_with_id)
onblockchange = true;
if ((worldTracker == null) && (onblockchange || onchunkpopulate || onchunkgenerate)) {
if (worldTracker == null)
worldTracker = new WorldTracker();
ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world));
ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world));
ServerChunkEvents.CHUNK_LOAD.register((world, chunk) -> worldTracker.handleChunkLoad(world, chunk));
ServerChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> worldTracker.handleChunkUnload(world, chunk));
ChunkDataEvents.SAVE.register((world, chunk) -> worldTracker.handleChunkDataSave(world, chunk));
if (onchunkpopulate || onchunkgenerate) {
CustomServerChunkEvents.CHUNK_GENERATE.register((world, chunk) -> worldTracker.handleChunkGenerate(world, chunk));
}
if (onblockchange) {
BlockEvents.BLOCK_EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos));
}
// Prime the known full chunks
if (onchunkgenerate && (server.getWorlds() != null)) {
for (ServerWorld world : server.getWorlds()) {
FabricWorld fw = getWorld(world);
if (fw == null) continue;
ServerChunkManager chunkManager = world.getChunkManager();
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = ((ThreadedAnvilChunkStorageAccessor) chunkManager.threadedAnvilChunkStorage).getChunkHolders();
for (Map.Entry<Long, ChunkHolder> k : chunks.long2ObjectEntrySet()) {
ChunkHolder ch = k.getValue();
Chunk c = null;
try {
c = ch.getSavingFuture().getNow(null);
} catch (Exception x) {
}
if (c == null) continue;
ChunkStatus cs = c.getStatus();
ChunkPos pos = ch.getPos();
if (cs == ChunkStatus.FULL) { // Cooked?
// Add it as known
addKnownChunk(fw, pos);
}
}
}
}
ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world));
ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world));
}
FabricWorld getWorldByName(String name) {
@ -890,4 +794,3 @@ public class DynmapPlugin {
}
}
}

View File

@ -301,8 +301,6 @@ compass-mode: newnorth
render-triggers:
- blockupdate
#- blockupdate-with-id
#- lightingupdate
- chunkpopulate
- chunkgenerate
#- none