forked from mirror/BlueMap
Add a trigger to render tiles for newly generated chunks on forge
This uses a workaround that is checking for each chunk-load-event, if that chunk is already present and generated on the world files. The chunk will most likely not be present on the worldfiles right after being generated, because it is usually not saved to disk right away.
This commit is contained in:
parent
e8fc7028d0
commit
41921c680a
@ -27,17 +27,22 @@
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
@ -46,11 +51,21 @@ public class ForgeEventForwarder {
|
||||
private ForgeMod mod;
|
||||
private Collection<ServerEventListener> eventListeners;
|
||||
|
||||
private Deque<WorldChunk> loadChunkEvents;
|
||||
private Thread loadChunkEventProcessor;
|
||||
|
||||
public ForgeEventForwarder(ForgeMod mod) {
|
||||
this.mod = mod;
|
||||
this.eventListeners = new ArrayList<>(1);
|
||||
|
||||
loadChunkEvents = new ConcurrentLinkedDeque<>();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
||||
//see processLoadChunkEvents JavaDoc comment
|
||||
loadChunkEventProcessor = new Thread(this::processLoadChunkEvents);
|
||||
loadChunkEventProcessor.setDaemon(true);
|
||||
loadChunkEventProcessor.start();
|
||||
}
|
||||
|
||||
public synchronized void addEventListener(ServerEventListener listener) {
|
||||
@ -113,4 +128,65 @@ public synchronized void onPlayerLeave(PlayerLoggedOutEvent evt) {
|
||||
for (ServerEventListener listener : eventListeners) listener.onPlayerLeave(uuid);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onChunkLoad(ChunkEvent.Load evt) {
|
||||
if (!(evt.getWorld() instanceof ServerWorld)) return;
|
||||
|
||||
try {
|
||||
UUID world = mod.getUUIDForWorld((ServerWorld) evt.getWorld());
|
||||
Vector2i chunk = new Vector2i(evt.getChunk().getPos().x, evt.getChunk().getPos().z);
|
||||
|
||||
Logger.global.logInfo("Adding chunk: " + chunk);
|
||||
|
||||
synchronized (loadChunkEvents) {
|
||||
loadChunkEvents.add(new WorldChunk(world, chunk));
|
||||
loadChunkEvents.notify();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logger.global.noFloodError("Failed to get the UUID for a world!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a workaround for forge not providing a way to detect if chunks are newly generated:
|
||||
* Each time a chunk-load-event occurs, it is (asynchronously) tested if the chunk is already generated on the world files.
|
||||
* If it is a new chunk it will likely not be saved to the disk right away.
|
||||
*/
|
||||
private void processLoadChunkEvents() {
|
||||
while (!Thread.interrupted()) {
|
||||
WorldChunk worldChunk;
|
||||
if (mod.getPlugin().isLoaded() && (worldChunk = loadChunkEvents.poll()) != null) {
|
||||
try {
|
||||
World world = mod.getPlugin().getWorld(worldChunk.world);
|
||||
if (world == null || world.isChunkGenerated(worldChunk.chunk)) continue;
|
||||
|
||||
for (ServerEventListener listener : eventListeners) listener.onChunkFinishedGeneration(worldChunk.world, worldChunk.chunk);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
Logger.global.noFloodWarning("processLoadChunkEventsError", "Failed to test if a chunk is newly generated:" + e);
|
||||
}
|
||||
} else {
|
||||
synchronized (loadChunkEvents) {
|
||||
try {
|
||||
loadChunkEvents.wait(10000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
private class WorldChunk {
|
||||
final UUID world;
|
||||
final Vector2i chunk;
|
||||
|
||||
public WorldChunk(UUID world, Vector2i chunk) {
|
||||
this.world = world;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -215,6 +215,10 @@ public MinecraftServer getServer() {
|
||||
return this.serverInstance;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return this.pluginInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
return onlinePlayerMap.values();
|
||||
|
@ -27,17 +27,22 @@
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
@ -46,11 +51,21 @@ public class ForgeEventForwarder {
|
||||
private ForgeMod mod;
|
||||
private Collection<ServerEventListener> eventListeners;
|
||||
|
||||
private Deque<WorldChunk> loadChunkEvents;
|
||||
private Thread loadChunkEventProcessor;
|
||||
|
||||
public ForgeEventForwarder(ForgeMod mod) {
|
||||
this.mod = mod;
|
||||
this.eventListeners = new ArrayList<>(1);
|
||||
|
||||
loadChunkEvents = new ConcurrentLinkedDeque<>();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
||||
//see processLoadChunkEvents JavaDoc comment
|
||||
loadChunkEventProcessor = new Thread(this::processLoadChunkEvents);
|
||||
loadChunkEventProcessor.setDaemon(true);
|
||||
loadChunkEventProcessor.start();
|
||||
}
|
||||
|
||||
public synchronized void addEventListener(ServerEventListener listener) {
|
||||
@ -113,4 +128,65 @@ public synchronized void onPlayerLeave(PlayerLoggedOutEvent evt) {
|
||||
for (ServerEventListener listener : eventListeners) listener.onPlayerLeave(uuid);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onChunkLoad(ChunkEvent.Load evt) {
|
||||
if (!(evt.getWorld() instanceof ServerWorld)) return;
|
||||
|
||||
try {
|
||||
UUID world = mod.getUUIDForWorld((ServerWorld) evt.getWorld());
|
||||
Vector2i chunk = new Vector2i(evt.getChunk().getPos().x, evt.getChunk().getPos().z);
|
||||
|
||||
Logger.global.logInfo("Adding chunk: " + chunk);
|
||||
|
||||
synchronized (loadChunkEvents) {
|
||||
loadChunkEvents.add(new WorldChunk(world, chunk));
|
||||
loadChunkEvents.notify();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logger.global.noFloodError("Failed to get the UUID for a world!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a workaround for forge not providing a way to detect if chunks are newly generated:
|
||||
* Each time a chunk-load-event occurs, it is (asynchronously) tested if the chunk is already generated on the world files.
|
||||
* If it is a new chunk it will likely not be saved to the disk right away.
|
||||
*/
|
||||
private void processLoadChunkEvents() {
|
||||
while (!Thread.interrupted()) {
|
||||
WorldChunk worldChunk;
|
||||
if (mod.getPlugin().isLoaded() && (worldChunk = loadChunkEvents.poll()) != null) {
|
||||
try {
|
||||
World world = mod.getPlugin().getWorld(worldChunk.world);
|
||||
if (world == null || world.isChunkGenerated(worldChunk.chunk)) continue;
|
||||
|
||||
for (ServerEventListener listener : eventListeners) listener.onChunkFinishedGeneration(worldChunk.world, worldChunk.chunk);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
Logger.global.noFloodWarning("processLoadChunkEventsError", "Failed to test if a chunk is newly generated:" + e);
|
||||
}
|
||||
} else {
|
||||
synchronized (loadChunkEvents) {
|
||||
try {
|
||||
loadChunkEvents.wait(10000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
private class WorldChunk {
|
||||
final UUID world;
|
||||
final Vector2i chunk;
|
||||
|
||||
public WorldChunk(UUID world, Vector2i chunk) {
|
||||
this.world = world;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -215,6 +215,10 @@ public MinecraftServer getServer() {
|
||||
return this.serverInstance;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return this.pluginInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
return onlinePlayerMap.values();
|
||||
|
@ -27,17 +27,22 @@
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
@ -46,11 +51,21 @@ public class ForgeEventForwarder {
|
||||
private ForgeMod mod;
|
||||
private Collection<ServerEventListener> eventListeners;
|
||||
|
||||
private Deque<WorldChunk> loadChunkEvents;
|
||||
private Thread loadChunkEventProcessor;
|
||||
|
||||
public ForgeEventForwarder(ForgeMod mod) {
|
||||
this.mod = mod;
|
||||
this.eventListeners = new ArrayList<>(1);
|
||||
|
||||
loadChunkEvents = new ConcurrentLinkedDeque<>();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
||||
//see processLoadChunkEvents JavaDoc comment
|
||||
loadChunkEventProcessor = new Thread(this::processLoadChunkEvents);
|
||||
loadChunkEventProcessor.setDaemon(true);
|
||||
loadChunkEventProcessor.start();
|
||||
}
|
||||
|
||||
public synchronized void addEventListener(ServerEventListener listener) {
|
||||
@ -113,4 +128,65 @@ public synchronized void onPlayerLeave(PlayerLoggedOutEvent evt) {
|
||||
for (ServerEventListener listener : eventListeners) listener.onPlayerLeave(uuid);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onChunkLoad(ChunkEvent.Load evt) {
|
||||
if (!(evt.getWorld() instanceof ServerWorld)) return;
|
||||
|
||||
try {
|
||||
UUID world = mod.getUUIDForWorld((ServerWorld) evt.getWorld());
|
||||
Vector2i chunk = new Vector2i(evt.getChunk().getPos().x, evt.getChunk().getPos().z);
|
||||
|
||||
Logger.global.logInfo("Adding chunk: " + chunk);
|
||||
|
||||
synchronized (loadChunkEvents) {
|
||||
loadChunkEvents.add(new WorldChunk(world, chunk));
|
||||
loadChunkEvents.notify();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logger.global.noFloodError("Failed to get the UUID for a world!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a workaround for forge not providing a way to detect if chunks are newly generated:
|
||||
* Each time a chunk-load-event occurs, it is (asynchronously) tested if the chunk is already generated on the world files.
|
||||
* If it is a new chunk it will likely not be saved to the disk right away.
|
||||
*/
|
||||
private void processLoadChunkEvents() {
|
||||
while (!Thread.interrupted()) {
|
||||
WorldChunk worldChunk;
|
||||
if (mod.getPlugin().isLoaded() && (worldChunk = loadChunkEvents.poll()) != null) {
|
||||
try {
|
||||
World world = mod.getPlugin().getWorld(worldChunk.world);
|
||||
if (world == null || world.isChunkGenerated(worldChunk.chunk)) continue;
|
||||
|
||||
for (ServerEventListener listener : eventListeners) listener.onChunkFinishedGeneration(worldChunk.world, worldChunk.chunk);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
Logger.global.noFloodWarning("processLoadChunkEventsError", "Failed to test if a chunk is newly generated:" + e);
|
||||
}
|
||||
} else {
|
||||
synchronized (loadChunkEvents) {
|
||||
try {
|
||||
loadChunkEvents.wait(10000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
private class WorldChunk {
|
||||
final UUID world;
|
||||
final Vector2i chunk;
|
||||
|
||||
public WorldChunk(UUID world, Vector2i chunk) {
|
||||
this.world = world;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -97,7 +97,6 @@ public ForgeMod() {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(FMLServerStartingEvent event) {
|
||||
this.worldUUIDs.clear();
|
||||
this.serverInstance = event.getServer();
|
||||
|
||||
//register commands
|
||||
@ -157,9 +156,7 @@ public UUID getUUIDForWorld(ServerWorld world) throws IOException {
|
||||
try {
|
||||
return worldUuidCache.get(world);
|
||||
} catch (RuntimeException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof IOException) throw (IOException) cause;
|
||||
else throw new IOException(cause);
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,6 +211,10 @@ public MinecraftServer getServer() {
|
||||
return this.serverInstance;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return this.pluginInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
return onlinePlayerMap.values();
|
||||
|
Loading…
Reference in New Issue
Block a user