It now able to join level without error spams!

This commit is contained in:
TomTheFurry
2022-07-01 17:05:52 +08:00
parent 17ffa3eaba
commit f2bfc50a31
11 changed files with 185 additions and 95 deletions
@@ -22,6 +22,7 @@ package com.seibel.lod.common;
import com.seibel.lod.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.networking.NetworkReceiver;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.core.api.internal.a7.SharedApi;
import com.seibel.lod.core.config.Config;
import com.seibel.lod.core.config.ConfigBase;
@@ -38,8 +39,8 @@ public class LodCommonMain {
forgeMethodCaller = caller;
}
DependencySetup.createInitialBindings();
DependencySetup.createSharedBindings();
SharedApi.init();
// if (!serverSided) {
// new NetworkReceiver().register_Client();
// } else {
@@ -16,12 +16,11 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.config.ConfigWrapper;
import com.seibel.lod.core.api.internal.a7.SharedApi;
import com.seibel.lod.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.IConfigWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
@@ -34,6 +33,10 @@ import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.config.LodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.server.dedicated.DedicatedServer;
/**
* Binds all necessary dependencies, so we
@@ -46,20 +49,25 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
* @version 12-1-2021
*/
public class DependencySetup {
public static void createInitialBindings()
public static void createSharedBindings()
{
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE); // TODO: Remove
SingletonHandler.bind(IConfigWrapper.class, ConfigWrapper.INSTANCE);
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
if (!SharedApi.inDedicatedEnvironment)
{
SingletonHandler.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton());
}
SingletonHandler.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
DependencySetupDoneCheck.isDone = true;
}
@Environment(EnvType.SERVER)
public static void createServerBindings() {
SingletonHandler.bind(IMinecraftSharedWrapper.class, MinecraftDedicatedServerWrapper.INSTANCE);
}
@Environment(EnvType.CLIENT)
public static void createClientBindings() {
SingletonHandler.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftSharedWrapper.class, MinecraftClientWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton());
}
}
@@ -22,6 +22,7 @@ package com.seibel.lod.common.wrappers.minecraft;
import java.io.File;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Objects;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.Window;
@@ -31,6 +32,7 @@ import com.seibel.lod.core.enums.ELodDirection;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
@@ -68,7 +70,7 @@ import org.jetbrains.annotations.Nullable;
* @author James Seibel
* @version 3-5-2022
*/
public class MinecraftClientWrapper implements IMinecraftClientWrapper
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
@@ -392,11 +394,16 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
@Override
public File getSinglePlayerServerFolder() {
return mc.getSingleplayerServer().getServerDirectory();
return Objects.requireNonNull(mc.getSingleplayerServer()).getServerDirectory();
}
@Override
public boolean isDedicatedServer() {
return false;
}
@Override
public File getInstallationDirectory() {
return mc.gameDirectory;
}
}
@@ -0,0 +1,23 @@
package com.seibel.lod.common.wrappers.minecraft;
import com.seibel.lod.core.api.internal.a7.SharedApi;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import net.minecraft.server.dedicated.DedicatedServer;
import java.io.File;
public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper {
public static final MinecraftDedicatedServerWrapper INSTANCE = new MinecraftDedicatedServerWrapper();
private MinecraftDedicatedServerWrapper() {}
public DedicatedServer dedicatedServer = null;
@Override
public boolean isDedicatedServer() {
return true;
}
@Override
public File getInstallationDirectory() {
if (dedicatedServer == null)
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
return dedicatedServer.getServerDirectory();
}
}
@@ -23,9 +23,15 @@ import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.core.a7.world.IServerWorld;
import com.seibel.lod.core.a7.world.WorldEnvironment;
import com.seibel.lod.core.api.internal.a7.SharedApi;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.DHChunkPos;
import com.seibel.lod.core.enums.EWorldType;
import com.seibel.lod.core.enums.ELevelType;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
@@ -33,6 +39,7 @@ import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -48,91 +55,104 @@ import org.jetbrains.annotations.Nullable;
*/
public class LevelWrapper implements ILevelWrapper
{
private static final ConcurrentMap<LevelAccessor, LevelWrapper> worldWrapperMap = new ConcurrentHashMap<>();
private final LevelAccessor world;
public final EWorldType worldType;
private static final ConcurrentMap<LevelAccessor, LevelWrapper> levelWrapperMap = new ConcurrentHashMap<>();
private final LevelAccessor level;
public final ELevelType levelType;
private static final IMinecraftSharedWrapper MC = SingletonHandler.get(IMinecraftSharedWrapper.class);
public LevelWrapper(LevelAccessor newWorld)
{
world = newWorld;
level = newWorld;
if (world.getClass() == ServerLevel.class)
worldType = EWorldType.ServerWorld;
else if (world.getClass() == ClientLevel.class)
worldType = EWorldType.ClientWorld;
if (level.getClass() == ServerLevel.class)
levelType = ELevelType.ServerLevel;
else if (level.getClass() == ClientLevel.class)
levelType = ELevelType.ClientLevel;
else
worldType = EWorldType.Unknown;
levelType = ELevelType.Unknown;
}
private static LevelAccessor getSinglePlayerServerLevel() {
MinecraftClientWrapper client = MinecraftClientWrapper.INSTANCE;
return client.mc.getSingleplayerServer().getPlayerList()
.getPlayer(client.mc.player.getUUID()).getLevel();
}
@Nullable
public static LevelWrapper getWorldWrapper(LevelAccessor world)
public static LevelWrapper getWorldWrapper(LevelAccessor level)
{
if (world == null) return null;
//first we check if the biome has already been wrapped
if(worldWrapperMap.containsKey(world) && worldWrapperMap.get(world) != null)
return worldWrapperMap.get(world);
if (level == null) return null;
if (level.isClientSide() && SharedApi.getEnvironment()
== WorldEnvironment.Client_Server) {
level = getSinglePlayerServerLevel();
}
//first we check if the level has already been wrapped
if(levelWrapperMap.containsKey(level) && levelWrapperMap.get(level) != null)
return levelWrapperMap.get(level);
//if it hasn't been created yet, we create it and save it in the map
LevelWrapper worldWrapper = new LevelWrapper(world);
worldWrapperMap.put(world, worldWrapper);
LevelWrapper levelWrapper = new LevelWrapper(level);
levelWrapperMap.put(level, levelWrapper);
//we return the newly created wrapper
return worldWrapper;
return levelWrapper;
}
public static void clearMap()
{
worldWrapperMap.clear();
levelWrapperMap.clear();
}
@Override
public EWorldType getWorldType()
public ELevelType getLevelType()
{
return worldType;
return levelType;
}
@Override
public DimensionTypeWrapper getDimensionType()
{
return DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
return DimensionTypeWrapper.getDimensionTypeWrapper(level.dimensionType());
}
@Override
public int getBlockLight(int x, int y, int z)
{
return world.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
return level.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
}
@Override
public int getSkyLight(int x, int y, int z)
{
return world.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
return level.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
}
public LevelAccessor getWorld()
public LevelAccessor getLevel()
{
return world;
return level;
}
@Override
public boolean hasCeiling()
{
return world.dimensionType().hasCeiling();
return level.dimensionType().hasCeiling();
}
@Override
public boolean hasSkyLight()
{
return world.dimensionType().hasSkyLight();
return level.dimensionType().hasSkyLight();
}
@Override
public int getHeight()
{
return world.getHeight();
return level.getHeight();
}
@Override
@@ -141,7 +161,7 @@ public class LevelWrapper implements ILevelWrapper
#if PRE_MC_1_17_1
return (short) 0;
#else
return (short) world.getMinBuildHeight();
return (short) level.getMinBuildHeight();
#endif
}
@@ -149,10 +169,10 @@ public class LevelWrapper implements ILevelWrapper
@Override
public File getSaveFolder() throws UnsupportedOperationException
{
if (worldType != EWorldType.ServerWorld)
if (levelType != ELevelType.ServerLevel)
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
ServerChunkCache chunkSource = ((ServerLevel) world).getChunkSource();
ServerChunkCache chunkSource = ((ServerLevel) level).getChunkSource();
return chunkSource.getDataStorage().dataFolder;
}
@@ -160,30 +180,30 @@ public class LevelWrapper implements ILevelWrapper
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
public ServerLevel getServerWorld() throws UnsupportedOperationException
{
if (worldType != EWorldType.ServerWorld)
if (levelType != ELevelType.ServerLevel)
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
return (ServerLevel) world;
return (ServerLevel) level;
}
@Override
public int getSeaLevel()
{
// TODO this is depreciated, what should we use instead?
return world.getSeaLevel();
return level.getSeaLevel();
}
@Override
public IChunkWrapper tryGetChunk(DHChunkPos pos) {
ChunkAccess chunk = world.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
ChunkAccess chunk = level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
if (chunk == null) return null;
return new ChunkWrapper(chunk, world);
return new ChunkWrapper(chunk, level);
}
@Override
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
// world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT!
ChunkSource source = world.getChunkSource();
ChunkSource source = level.getChunkSource();
return source.hasChunk(chunkX, chunkZ);
}
}
@@ -359,7 +359,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
EVENT_LOGGER.warn("If it does crash, set Distant Generation to OFF or Generation Mode to None.");
}
}
params = new GlobalParameters((ServerLevel) ((LevelWrapper) serverlevel).getWorld(), lodBuilder, lodDim);
params = new GlobalParameters((ServerLevel) ((LevelWrapper) serverlevel).getLevel(), lodBuilder, lodDim);
}
@SuppressWarnings("resource")
@@ -0,0 +1,26 @@
package com.seibel.lod.fabric;
import com.seibel.lod.common.wrappers.DependencySetup;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
public class FabricClientMain implements ClientModInitializer {
public static FabricClientProxy client_proxy;
public static FabricServerProxy server_proxy;
// Do if implements ClientModInitializer
// This loads the mod before minecraft loads which causes a lot of issues
@Override
public void onInitializeClient() {
DependencySetup.createClientBindings();
FabricMain.init();
server_proxy = new FabricServerProxy(false);
server_proxy.registerEvents();
client_proxy = new FabricClientProxy();
client_proxy.registerEvents();
ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> FabricMain.postInit());
}
}
@@ -0,0 +1,30 @@
package com.seibel.lod.fabric;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
import com.seibel.lod.core.util.LodUtil;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.server.dedicated.DedicatedServer;
public class FabricDedicatedServerMain implements DedicatedServerModInitializer {
public static FabricServerProxy server_proxy;
public boolean hasPostSetupDone = false;
@Override
public void onInitializeServer() {
DependencySetup.createServerBindings();
FabricMain.init();
server_proxy = new FabricServerProxy(true);
server_proxy.registerEvents();
ServerLifecycleEvents.SERVER_STARTING.register((server) -> {
if (hasPostSetupDone) return;
hasPostSetupDone = true;
FabricMain.postInit();
LodUtil.assertTrue(server instanceof DedicatedServer);
MinecraftDedicatedServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer) server;
});
}
}
@@ -20,6 +20,7 @@
package com.seibel.lod.fabric;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.internal.a7.SharedApi;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
@@ -51,41 +52,17 @@ import java.lang.invoke.MethodHandles;
* @author Ran
* @version 12-1-2021
*/
public class FabricMain implements ClientModInitializer, DedicatedServerModInitializer
public class FabricMain
{
// This is a client mod so it should implement ClientModInitializer and in fabric.mod.json it should have "environment": "client"
// Once it works on servers change the implement to ModInitializer and in fabric.mod.json it should be "environment": "*"
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
public static FabricClientProxy client_proxy;
public static FabricServerProxy server_proxy;
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
// Do if implements ClientModInitializer
// This loads the mod before minecraft loads which causes a lot of issues
@Override
public void onInitializeClient() {
SharedApi.inDedicatedEnvironment = false;
init();
ClientLifecycleEvents.CLIENT_STARTED.register(FabricMain::postInit);
}
@Override
public void onInitializeServer() {
SharedApi.inDedicatedEnvironment = true;
init();
postInit(null); // TODO: Check if init in here is ok
}
public static void postInit(Minecraft minecraft) {
public static void postInit() {
LOGGER.info("Post-Initializing Mod");
FabricDependencySetup.runDelayedSetup();
LOGGER.info("Mod Post-Initialized");
}
// This loads the mod after minecraft loads which doesn't causes a lot of issues
public static void init() {
LOGGER.info("Initializing Mod");
@@ -95,13 +72,6 @@ public class FabricMain implements ClientModInitializer, DedicatedServerModIniti
LodCommonMain.initConfig();
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
if (!SharedApi.inDedicatedEnvironment) {
client_proxy = new FabricClientProxy();
client_proxy.registerEvents();
}
server_proxy = new FabricServerProxy();
server_proxy.registerEvents();
if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) {
ModAccessorHandler.bind(ISodiumAccessor.class, new SodiumAccessor());
}
@@ -31,6 +31,11 @@ import org.apache.logging.log4j.Logger;
public class FabricServerProxy {
private final ServerApi serverApi = ServerApi.INSTANCE;
private static final Logger LOGGER = DhLoggerBuilder.getLogger("FabricServerProxy");
private final boolean isDedicated;
public FabricServerProxy(boolean isDedicated) {
this.isDedicated = isDedicated;
}
private boolean isValidTime() {
//FIXME: return true immediately if this is a dedicated server
@@ -57,7 +62,7 @@ public class FabricServerProxy {
// ServerWorldLoadEvent
//TODO: Check if both of this use the correct timed events. (i.e. is it 'ed' or 'ing' one?)
ServerLifecycleEvents.SERVER_STARTING.register((server) -> {
if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(SharedApi.inDedicatedEnvironment);
if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(isDedicated);
});
// ServerWorldUnloadEvent
ServerLifecycleEvents.SERVER_STOPPED.register((server) -> {
+2 -2
View File
@@ -19,10 +19,10 @@
"environment": "*",
"entrypoints": {
"client": [
"com.seibel.lod.fabric.FabricMain"
"com.seibel.lod.fabric.FabricClientMain"
],
"server": [
"com.seibel.lod.fabric.FabricMain"
"com.seibel.lod.fabric.FabricDedicatedServerMain"
],
"modmenu": [