Skip to content

Commit

Permalink
Switch to entities unload event for new paper chunkloading system
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Oct 18, 2022
1 parent b88dbf2 commit 84e5940
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 46 deletions.
102 changes: 56 additions & 46 deletions main/src/main/java/net/citizensnpcs/EventListen.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.citizensnpcs;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -202,53 +203,9 @@ public void onChunkLoad(ChunkLoadEvent event) {

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onChunkUnload(final ChunkUnloadEvent event) {
final List<NPC> toDespawn = Lists.newArrayList();
for (Entity entity : event.getChunk().getEntities()) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(entity);
if (npc == null || !npc.isSpawned())
continue;
toDespawn.add(npc);
}
if (toDespawn.isEmpty())
if (chunkEventListener != null)
return;
ChunkCoord coord = new ChunkCoord(event.getChunk());
boolean loadChunk = false;
for (NPC npc : toDespawn) {
if (!npc.despawn(DespawnReason.CHUNK_UNLOAD)) {
if (!(event instanceof Cancellable)) {
if (Messaging.isDebugging()) {
Messaging.debug("Reloading chunk because", npc, "couldn't despawn");
}
loadChunk = true;
toRespawn.put(coord, npc);
continue;
}
((Cancellable) event).setCancelled(true);
Messaging.debug("Cancelled chunk unload at", coord);
respawnAllFromCoord(coord, event);
return;
}
toRespawn.put(coord, npc);
if (Messaging.isDebugging()) {
Messaging.debug("Despawned", npc, "due to chunk unload at", coord);
}
}
if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean()) {
new Exception("CITIZENS CHUNK UNLOAD DEBUG " + coord).printStackTrace();
}
if (loadChunk) {
if (Messaging.isDebugging()) {
Messaging.debug("Loading chunk in 10 ticks due to forced chunk load at", coord);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
if (!event.getChunk().isLoaded()) {
event.getChunk().load();
}
}
}, 10);
}
unloadNPCs(event, Arrays.asList(event.getChunk().getEntities()));
}

@EventHandler(priority = EventPriority.MONITOR)
Expand Down Expand Up @@ -704,6 +661,7 @@ public void onWorldLoad(WorldLoadEvent event) {

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onWorldUnload(WorldUnloadEvent event) {
System.out.println(event.getWorld());
for (NPC npc : getAllNPCs()) {
if (npc == null || !npc.isSpawned() || !npc.getEntity().getWorld().equals(event.getWorld()))
continue;
Expand Down Expand Up @@ -771,5 +729,57 @@ private boolean spawn(NPC npc) {
return npc.spawn(spawn, SpawnReason.CHUNK_LOAD);
}

void unloadNPCs(ChunkEvent event, List<Entity> entities) {
final List<NPC> toDespawn = Lists.newArrayList();
for (Entity entity : entities) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(entity);
// XXX : npc#isSpawned() checks entity valid status which is now inconsistent on chunk unload between
// different server software (e.g. Paper and Spigot), so check for npc.getEntity() == null instead.
if (npc == null || npc.getEntity() == null)
continue;
toDespawn.add(npc);
}
if (toDespawn.isEmpty())
return;
ChunkCoord coord = new ChunkCoord(event.getChunk());
boolean loadChunk = false;
for (NPC npc : toDespawn) {
if (!npc.despawn(DespawnReason.CHUNK_UNLOAD)) {
if (!(event instanceof Cancellable)) {
if (Messaging.isDebugging()) {
Messaging.debug("Reloading chunk because", npc, "couldn't despawn");
}
loadChunk = true;
toRespawn.put(coord, npc);
continue;
}
((Cancellable) event).setCancelled(true);
Messaging.debug("Cancelled chunk unload at", coord);
respawnAllFromCoord(coord, event);
return;
}
toRespawn.put(coord, npc);
if (Messaging.isDebugging()) {
Messaging.debug("Despawned", npc, "due to chunk unload at", coord);
}
}
if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean()) {
new Exception("CITIZENS CHUNK UNLOAD DEBUG " + coord).printStackTrace();
}
if (loadChunk) {
if (Messaging.isDebugging()) {
Messaging.debug("Loading chunk in 10 ticks due to forced chunk load at", coord);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
if (!event.getChunk().isLoaded()) {
event.getChunk().load();
}
}
}, 10);
}
}

private static boolean SUPPORT_STOP_USE_ITEM = true;
}
6 changes: 6 additions & 0 deletions main/src/main/java/net/citizensnpcs/EventListenChunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.EntitiesLoadEvent;
import org.bukkit.event.world.EntitiesUnloadEvent;

public class EventListenChunk implements Listener {
EventListen listen;
Expand All @@ -16,4 +17,9 @@ public class EventListenChunk implements Listener {
public void onEntitiesLoad(EntitiesLoadEvent event) {
listen.loadNPCs(event);
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onEntitiesUnload(EntitiesUnloadEvent event) {
listen.unloadNPCs(event, event.getEntities());
}
}

0 comments on commit 84e5940

Please sign in to comment.