It now able to join level without error spams!

This commit is contained in:
TomTheFurry
2022-07-01 17:05:52 +08:00
parent bdc8384c49
commit 1c63dd5183
8 changed files with 63 additions and 43 deletions
@@ -9,28 +9,46 @@ import com.seibel.lod.core.a7.render.RenderBufferHandler;
import com.seibel.lod.core.a7.save.structure.LocalSaveStructure;
import com.seibel.lod.core.config.Config;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.render.a7LodRenderer;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
import org.apache.logging.log4j.Logger;
import java.util.concurrent.CompletableFuture;
public class DhClientServerLevel implements IClientLevel, IServerLevel {
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class);
public final LocalSaveStructure save;
public final LocalDataFileHandler dataFileHandler;
public final RenderFileHandler renderFileHandler;
public final RenderBufferHandler renderBufferHandler; //TODO: Should this be owned by renderer?
public RenderFileHandler renderFileHandler = null;
public RenderBufferHandler renderBufferHandler = null; //TODO: Should this be owned by renderer?
public final ILevelWrapper level;
public a7LodRenderer renderer = null;
public LodQuadTree tree;
public LodQuadTree tree = null;
public DhClientServerLevel(LocalSaveStructure save, ILevelWrapper level) {
this.level = level;
this.save = save;
dataFileHandler = new LocalDataFileHandler(this, save.getDataFolder(level));
}
public void clientTick() {
if (tree != null) tree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos()));
if (renderBufferHandler != null) renderBufferHandler.update();
}
public void serverTick() {
//TODO Update network packet and stuff or state or etc..
}
public void startRenderer() {
if (renderBufferHandler != null) {
LOGGER.warn("Tried to call startRenderer() on the clientServerLevel {} when renderer is already setup!", level);
return;
}
renderFileHandler = new RenderFileHandler(dataFileHandler, this, save.getRenderCacheFolder(level));
tree = new LodQuadTree(Config.Client.Graphics.Quality.lodChunkRenderDistance.get()*16,
MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, renderFileHandler);
@@ -38,20 +56,12 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
FileScanner.scanFile(save, level, dataFileHandler, renderFileHandler);
}
public void clientTick() {
tree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos()));
renderBufferHandler.update();
}
public void serverTick() {
//TODO Update network packet and stuff or state or etc..
}
public void startRenderer() {
//TODO
}
@Override
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler) {
if (renderBufferHandler == null) {
LOGGER.error("Tried to call render() on the clientServerLevel {} when renderer has not been started!", level);
return;
}
if (renderer == null) {
renderer = new a7LodRenderer(this);
}
@@ -59,8 +69,16 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
}
public void stopRenderer() {
if (renderBufferHandler == null) {
LOGGER.warn("Tried to call stopRenderer() on the clientServerLevel {} when renderer is already closed!", level);
return;
}
renderBufferHandler.close();
renderBufferHandler = null;
tree = null; //TODO Close the tree
renderFileHandler.flushAndSave(); //Ignore the completion feature so that this action is async
//TODO
renderFileHandler.close();
renderFileHandler = null;
}
@Override
@@ -80,14 +98,13 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
@Override
public CompletableFuture<Void> save() {
return renderFileHandler.flushAndSave();
return renderFileHandler == null ? dataFileHandler.flushAndSave() : renderFileHandler.flushAndSave();
//Note: saving renderFileHandler will also save the dataFileHandler.
}
@Override
public void close() {
renderFileHandler.close();
//Note: Closing renderFileHandler will also close the dataFileHandler.
dataFileHandler.close();
}
@Override
@@ -22,7 +22,7 @@ package com.seibel.lod.core.api.internal;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.worldGeneration.BatchGenerator;
import com.seibel.lod.core.config.Config;
import com.seibel.lod.core.enums.EWorldType;
import com.seibel.lod.core.enums.ELevelType;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.objects.DHChunkPos;
@@ -129,14 +129,14 @@ public class EventApi
if (ENABLE_STACK_DUMP_LOGGING)
LOGGER.info(
"WorldLoadEvent called here for "
+ (world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel"),
+ (world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel"),
new RuntimeException());
// Always ignore ServerWorld event
if (world.getWorldType() == EWorldType.ServerWorld)
if (world.getLevelType() == ELevelType.ServerLevel)
return;
isCurrentlyOnSinglePlayerServer = MC.hasSinglePlayerServer();
if (!InternalApiShared.isShuttingDown) LOGGER.warn("WorldLoadEvent called on {} while another world is loaded!",
(world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel"));
(world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel"));
InternalApiShared.isShuttingDown = false;
//DataPointUtil.WORLD_HEIGHT = world.getHeight();
LodBuilder.MIN_WORLD_HEIGHT = world.getMinHeight(); // This updates the World height
@@ -162,13 +162,13 @@ public class EventApi
if (ENABLE_STACK_DUMP_LOGGING)
LOGGER.info(
"WorldUnloadEvent called here for "
+ (world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel"),
+ (world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel"),
new RuntimeException());
// If it's single player, ignore the client side world unload event
// Note: using isCurrentlyOnSinglePlayerServer as often API call unload event
// AFTER setting MC to not be in a singlePlayerServer
if (isCurrentlyOnSinglePlayerServer && world.getWorldType() == EWorldType.ClientWorld)
if (isCurrentlyOnSinglePlayerServer && world.getLevelType() == ELevelType.ClientLevel)
return;
// if this isn't done unfinished tasks may be left in the queue
@@ -179,18 +179,20 @@ public class ClientApi
profiler.pop();
}
public void renderLods(ILevelWrapper world, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
public void renderLods(ILevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
{
IProfilerWrapper profiler = MC.getProfiler();
profiler.pop(); // get out of "terrain"
profiler.push("DH-RenderLevel");
try {
if (!MC.playerExists()) return;
if (world == null) return;
DhWorld DhWorld = SharedApi.currentWorld;
if (DhWorld == null) return;
if (levelWrapper == null) return;
DhWorld dhWorld = SharedApi.currentWorld;
if (dhWorld == null) return;
if (!(SharedApi.currentWorld instanceof IClientWorld)) return;
IClientLevel level = (IClientLevel)SharedApi.currentWorld;
//FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting
IClientLevel level = (IClientLevel) dhWorld.getOrLoadLevel(levelWrapper);
if (level == null) return; //Level is not ready yet.
if (prefLoggerEnabled) {
level.dumpRamUsage();
@@ -1,5 +1,6 @@
package com.seibel.lod.core.api.internal.a7;
import com.seibel.lod.core.a7.Initializer;
import com.seibel.lod.core.a7.world.WorldEnvironment;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.a7.world.DhWorld;
@@ -10,12 +11,11 @@ public class SharedApi {
public static final Logger LOGGER = DhLoggerBuilder.getLogger("DH Events");
public static IMinecraftSharedWrapper MC;
public static DhWorld currentWorld;
//TODO: Should this be in core and able to be accessed by core, or should this be in common, and only effect
// how common calls back into the internal APIs?
public static boolean inDedicatedEnvironment;
public static WorldEnvironment getEnvironment() {
return currentWorld==null ? null : currentWorld.environment;
}
public static void init() {
Initializer.init();
}
}
@@ -25,9 +25,9 @@ package com.seibel.lod.core.enums;
* @author James Seibel
* @version 11-12-2021
*/
public enum EWorldType
public enum ELevelType
{
ServerWorld,
ClientWorld,
ServerLevel,
ClientLevel,
Unknown
}
@@ -70,8 +70,8 @@ public class SingletonHandler
return foundObject;
}
/**
* Should only be called after all Binds have been done.
* Calls the delayedSetup method for each dependency. <br> <br>
@@ -6,7 +6,8 @@ import java.io.File;
//TODO: Maybe have IMCClientWrapper & IMCDedicatedWrapper extend this interface???
public interface IMinecraftSharedWrapper extends IBindable {
boolean isServerJar();
boolean isDedicatedServer();
File getInstallationDirectory();
}
@@ -21,7 +21,7 @@ package com.seibel.lod.core.wrapperInterfaces.world;
import java.io.File;
import com.seibel.lod.core.enums.EWorldType;
import com.seibel.lod.core.enums.ELevelType;
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
import com.seibel.lod.core.objects.DHChunkPos;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
@@ -36,7 +36,7 @@ public interface ILevelWrapper extends IBindable
{
IDimensionTypeWrapper getDimensionType();
EWorldType getWorldType();
ELevelType getLevelType();
int getBlockLight(int x, int y, int z);