diff --git a/src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java b/src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java new file mode 100644 index 000000000..e027a7aa7 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java @@ -0,0 +1,7 @@ +package com.seibel.lod.core.a7; + +public enum WorldEnvironment { + Client_Only, + Client_Server, + Server_Only +} diff --git a/src/main/java/com/seibel/lod/core/a7/data/DataFileHandler.java b/src/main/java/com/seibel/lod/core/a7/data/DataFileHandler.java index 119813ded..9d0d9ab89 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/DataFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/data/DataFileHandler.java @@ -2,7 +2,7 @@ package com.seibel.lod.core.a7.data; import com.google.common.collect.HashMultimap; import com.seibel.lod.core.a7.RenderDataProvider; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.datatype.column.DataSourceSaver; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.render.RenderDataSource; diff --git a/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java b/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java index 4057435c8..a8b31ac10 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.a7.data; import com.google.common.collect.HashMultimap; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.io.file.DataMetaFile; import java.io.File; diff --git a/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java b/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java index 473a9ea56..d2cde00a6 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java +++ b/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java @@ -1,6 +1,6 @@ package com.seibel.lod.core.a7.data; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import java.io.File; import java.util.List; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java index 74231cee8..4e0651f86 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java @@ -5,7 +5,7 @@ import com.seibel.lod.core.a7.data.LodDataSource; import com.seibel.lod.core.a7.data.OldFileConverter; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.enums.config.EVerticalQuality; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.objects.a7.data.*; import com.seibel.lod.core.a7.io.file.DataMetaFile; import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java index c3e296a17..06293ba86 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java @@ -6,7 +6,7 @@ import com.seibel.lod.core.a7.io.MetaFile; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.enums.config.EVerticalQuality; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.io.file.DataMetaFile; import java.io.*; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java index e87fa0746..eeacbb0b8 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java @@ -5,7 +5,7 @@ import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.render.RenderBuffer; import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.LodQuadTree; import com.seibel.lod.core.a7.LodSection; import com.seibel.lod.core.a7.render.RenderDataSource; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java index ace4ca734..0b2ba37eb 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java @@ -5,7 +5,7 @@ import com.seibel.lod.core.a7.datatype.full.FullDatatype; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.render.RenderDataSource; import com.seibel.lod.core.a7.render.RenderDataSourceLoader; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.objects.a7.data.DataFile; import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.LodUtil; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java index 6e871bdbc..fd2c6c14b 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java @@ -5,7 +5,7 @@ import com.seibel.lod.core.a7.data.DataSourceLoader; import com.seibel.lod.core.a7.data.LodDataSource; import com.seibel.lod.core.a7.io.MetaFile; import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import java.io.File; import java.io.IOException; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java index 3310e2f5b..1495f6888 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java @@ -3,7 +3,7 @@ package com.seibel.lod.core.a7.datatype.column; import com.seibel.lod.core.a7.data.DataSourceLoader; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import java.io.DataInputStream; import java.io.IOException; diff --git a/src/main/java/com/seibel/lod/core/a7/io/DHFolderHandler.java b/src/main/java/com/seibel/lod/core/a7/io/DHFolderHandler.java index 914901700..406a2d3ac 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/DHFolderHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/io/DHFolderHandler.java @@ -44,30 +44,6 @@ public class DHFolderHandler { throw new RuntimeException("Critical error: Unable to get world folder directory", e); } - // move any old data folders if they exist - File[] subFolders = dimensionFolder.listFiles(); - if (subFolders != null) { - for (File folder : subFolders) - { - //FIXME: Errr... What to do here? - /* - if (VerticalQuality.getByName(folder.getName()) != null) - { - // this is a LOD save folder - // create a new sub dimension and move the data into it - File newDimension = GetDimensionFolder(dimensionType, subDimensionName); - newDimension.mkdirs(); - - File oldDataNewPath = new File(newDimension.getPath() + File.separatorChar + folder.getName()); - Files.move(folder.toPath(), oldDataNewPath.toPath()); - } - else - { - // ignore this folder - } - */ - } - } return dimensionFolder; } private static String getServerFolderName() diff --git a/src/main/java/com/seibel/lod/core/a7/io/LevelToFileMatcher.java b/src/main/java/com/seibel/lod/core/a7/io/LevelToFileMatcher.java index 0e1524b5c..e8d71e941 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/LevelToFileMatcher.java +++ b/src/main/java/com/seibel/lod/core/a7/io/LevelToFileMatcher.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.a7.io; +import com.seibel.lod.core.a7.world.DhClientWorld; import com.seibel.lod.core.api.internal.InternalApiShared; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig; @@ -14,49 +15,53 @@ import com.seibel.lod.core.handlers.dimensionFinder.SubDimCompare; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.objects.DHRegionPos; -import com.seibel.lod.core.a7.DHLevel; -import com.seibel.lod.core.a7.DHWorld; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.LodRegion; import com.seibel.lod.core.util.DataPointUtil; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.LogManager; import java.io.File; import java.io.IOException; -import java.util.Arrays; +import java.util.Objects; import java.util.UUID; +import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicBoolean; -public class LevelToFileMatcher { - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); +public class LevelToFileMatcher implements AutoCloseable { + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(LodDimensionFinder.class), () -> Config.Client.Advanced.Debugging.DebugSwitch.logFileSubDimEvent.get()); - /** Increasing this will increase accuracy but increase calculation time */ - private static final EVerticalQuality VERTICAL_QUALITY_TO_TEST_WITH = EVerticalQuality.LOW; + private final ExecutorService matcherThread = LodUtil.makeSingleThreadPool("Level-To-File-Matcher"); - public static final String THREAD_NAME = "Level-To-File-Matcher"; - - private PlayerData playerData = new PlayerData(MC); + private PlayerData playerData = null; private PlayerData firstSeenPlayerData = null; - private volatile DHLevel foundLevel = null; - /** If true the LodDimensionFileHelper is attempting to determine the folder for this dimension */ private final AtomicBoolean determiningWorldFolder = new AtomicBoolean(false); + private final ILevelWrapper currentLevel; + private final DhClientWorld world; + private volatile DHLevel foundLevel = null; + private final File[] potentialFiles; + private final File levelsFolder; - private final IWorldWrapper currentWorld; - private final File worldFolder; - private final DHWorld dhWorld; - - public LevelToFileMatcher(DHWorld dhWorld, File worldFolder, IWorldWrapper targetWorld) { - this.currentWorld = targetWorld; - this.worldFolder = worldFolder; - this.dhWorld = dhWorld; + public LevelToFileMatcher(DhClientWorld DhWorld, ILevelWrapper targetWorld, File levelsFolder, File[] potentialFiles) { + this.currentLevel = targetWorld; + this.world = DhWorld; + this.potentialFiles = potentialFiles; + this.levelsFolder = levelsFolder; + if (potentialFiles.length == 0) { + String newId = UUID.randomUUID().toString(); + LOGGER.info("No potential level files found. Creating a new sub dimension with ID {}...", + LodUtil.shortenString(newId, 8)); + File folder = new File(levelsFolder, newId); + foundLevel = new DHLevel(world, folder, targetWorld); + } } // May return null, where at this moment the level is not yet known @@ -65,87 +70,30 @@ public class LevelToFileMatcher { return foundLevel; } - public IWorldWrapper getTargetWorld() { - return currentWorld; + public boolean isFindingLevel(ILevelWrapper level) { + return Objects.equals(level, currentLevel); } private void tick() { + if (foundLevel != null) return; // prevent multiple threads running at the same time - - if (Config.Client.Multiplayer.multiDimensionRequiredSimilarity.get() == 0 || MC.hasSinglePlayerServer()) { - File saveDir = getLevelFolderWithoutSimilarityMatching(); - foundLevel = new DHLevel(dhWorld, saveDir, currentWorld); - } else { - if (determiningWorldFolder.getAndSet(true)) return; - //FIXME: Use a thread pool - Thread thread = new Thread(() -> - { - try { - // attempt to get the file handler - File saveDir = attemptToDetermineSubDimensionFolder(); - if (saveDir == null) return; - foundLevel = new DHLevel(dhWorld, saveDir, currentWorld); - } catch (IOException e) { - LOGGER.error("Unable to set the dimension file handler for level [" + currentWorld + "]. Error: ", e); - } finally { - // make sure we unlock this method - determiningWorldFolder.set(false); - } - }); - thread.setName(THREAD_NAME); - thread.start(); - } - } - - /** - * Returns the default save folder if it exists - * otherwise the first valid subDimension folder lexicographically. - */ - private File getLevelFolderWithoutSimilarityMatching() - { - File[] subDirs = worldFolder.listFiles(); - File levelFolder = null; - // check if a sub dimension folder exists - if (subDirs != null) + if (determiningWorldFolder.getAndSet(true)) return; + matcherThread.submit(() -> { - // at least one folder exists - LOGGER.info("Potential Sub Dimension folders: [" + subDirs.length + "]"); - - Arrays.sort(subDirs); // listFiles isn't necessarily sorted - for (File potentialFolder : subDirs) - { - if (isValidLevelFolder(potentialFolder)) - { - if (potentialFolder.getName().equals(currentWorld.getDimensionType().getDimensionName())) - { - // use the default save folder if possible - levelFolder = potentialFolder; - break; - } - else if (levelFolder == null) - { - // only get the first non-default sub folder - levelFolder = potentialFolder; - } - } + try { + // attempt to get the file handler + File saveDir = attemptToDetermineSubDimensionFolder(); + if (saveDir == null) return; + foundLevel = new DHLevel(world, saveDir, currentLevel); + } catch (IOException e) { + LOGGER.error("Unable to set the dimension file handler for level [" + currentLevel + "]. Error: ", e); + } finally { + // make sure we unlock this method + determiningWorldFolder.set(false); } - } - - // if no valid sub dimension was found, create a new one - if (levelFolder == null) - { - levelFolder = new File(worldFolder, currentWorld.getDimensionType().getDimensionName()); - levelFolder.mkdirs(); - LOGGER.info("Default Sub Dimension not found. Creating: [" + currentWorld.getDimensionType().getDimensionName() + "]"); - } - else - { - LOGGER.info("Default Sub Dimension set to: [" + LodUtil.shortenString(levelFolder.getName(), 8) + "...]"); - } - return levelFolder; + }); } - /** * Currently this method checks a single chunk (where the player is) * and compares it against the same chunk position in the other dimension worlds to @@ -155,36 +103,36 @@ public class LevelToFileMatcher { */ public File attemptToDetermineSubDimensionFolder() throws IOException { - if (firstSeenPlayerData == null) - { - firstSeenPlayerData = playerData; - playerData = new PlayerData(MC); + { // Update PlayerData + PlayerData data = PlayerData.tryGetPlayerData(MC_CLIENT); + if (data != null) { + if (firstSeenPlayerData == null) { + firstSeenPlayerData = data; + } + playerData = data; + } } // relevant positions DHChunkPos playerChunkPos = new DHChunkPos(playerData.playerBlockPos); int startingBlockPosX = playerChunkPos.getMinBlockX(); int startingBlockPosZ = playerChunkPos.getMinBlockZ(); - DHRegionPos playerRegionPos = new DHRegionPos(playerChunkPos); // chunk from the newly loaded level - IChunkWrapper newlyLoadedChunk = MC.getWrappedClientWorld().tryGetChunk(playerChunkPos); + IChunkWrapper newlyLoadedChunk = MC_CLIENT.getWrappedClientWorld().tryGetChunk(playerChunkPos); // check if this chunk is valid to test if (!CanDetermineLevelFolder(newlyLoadedChunk)) return null; - // create a temporary dimension to store the test LOD - LodDimension newlyLoadedDim = new LodDimension(MC.getCurrentDimension(), 1, null, false); - newlyLoadedDim.move(playerRegionPos); - newlyLoadedDim.regions.set(playerRegionPos.x, playerRegionPos.z, new LodRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerRegionPos, VERTICAL_QUALITY_TO_TEST_WITH)); - + //TODO: Compute a ChunkData from current chunk. + /* // generate a LOD to test against boolean lodGenerated = InternalApiShared.lodBuilder.generateLodNodeFromChunk(newlyLoadedDim, newlyLoadedChunk, new LodBuilderConfig(EDistanceGenerationMode.FULL), true, true); if (!lodGenerated) return null; // log the start of this attempt - LOGGER.info("Attempting to determine sub-dimension for [" + MC.getCurrentDimension().getDimensionName() + "]"); + LOGGER.info("Attempting to determine sub-dimension for [" + MC_CLIENT.getCurrentDimension().getDimensionName() + "]"); LOGGER.info("Player block pos in dimension: [" + playerData.playerBlockPos.getX() + "," + playerData.playerBlockPos.getY() + "," + playerData.playerBlockPos.getZ() + "]"); // new chunk data @@ -215,21 +163,23 @@ public class LevelToFileMatcher { LOGGER.warn(message); } return null; - } + }*/ + // compare each world with the newly loaded one SubDimCompare mostSimilarSubDim = null; - File[] levelFolders = worldFolder.listFiles(File::isDirectory); + File[] levelFolders = potentialFiles; LOGGER.info("Potential Sub Dimension folders: [" + levelFolders.length + "]"); for (File testLevelFolder : levelFolders) { - //FIXME: Err... what? The filter should have already filtered this out... Is this needed? - if (!testLevelFolder.isDirectory()) continue; - if (!isValidLevelFolder(testLevelFolder)) continue; LOGGER.info("Testing level folder: [" + LodUtil.shortenString(testLevelFolder.getName(), 8) + "]"); try { + // TODO: Try load a data file overlapping the playerChunkPos from ClientOnlySaveStructure, + // and then use it to compare chunk data to current chunk. + + /* // get a LOD from this dimension folder LodDimension tempLodDim = new LodDimension(null, 1, null, false); tempLodDim.move(playerRegionPos); @@ -291,6 +241,7 @@ public class LevelToFileMatcher { } LOGGER.info("Sub dimension [" + LodUtil.shortenString(testLevelFolder.getName(), 8) + "...] is current dimension probability: " + LodUtil.shortenString(subDimCompare.getPercentEqual() + "", 5) + " (" + equalDataPoints + "/" + totalDataPointCount + ")"); +*/ } catch (Exception e) { @@ -299,7 +250,7 @@ public class LevelToFileMatcher { } } - // TODO if two sub dimensions contain the same LODs merge them + // TODO if two sub dimensions contain the same LODs merge them??? // the first seen player data is no longer needed, the sub dimension has been determined firstSeenPlayerData = null; @@ -320,7 +271,7 @@ public class LevelToFileMatcher { String newId = UUID.randomUUID().toString(); String message = "No suitable sub dimension found. The highest equality was [" + LodUtil.shortenString(highestEqualityPercent + "", 5) + "]. Creating a new sub dimension with ID: " + LodUtil.shortenString(newId, 8) + "..."; LOGGER.info(message); - File folder = new File(worldFolder, newId); + File folder = new File(levelsFolder, newId); folder.mkdirs(); return folder; } @@ -333,49 +284,8 @@ public class LevelToFileMatcher { return LodBuilder.canGenerateLodFromChunk(chunk); } - - /** Used for debugging, returns true if every data point is 0 */ - private static boolean isDataEmpty(long[][][] chunkData) - { - for (long[][] xArray : chunkData) - { - for (long[] zArray : xArray) - { - for (long dataPoint : zArray) - { - if (dataPoint != 0) - { - return false; - } - } - } - } - - return true; + @Override + public void close() { + matcherThread.shutdownNow(); } - - /** Returns true if the given folder holds valid Lod Dimension data */ - public static boolean isValidLevelFolder(File potentialFolder) - { - if (!potentialFolder.isDirectory()) - // it needs to be a folder - return false; - - if (potentialFolder.listFiles() == null) - // it needs to have folders in it - return false; - - // check if there is at least one VerticalQuality folder in this directory - for (File internalFolder : potentialFolder.listFiles()) - { - if (EVerticalQuality.getByName(internalFolder.getName()) != null) - { - // one of the internal folders is a VerticalQuality folder - return true; - } - } - - return false; - } - } diff --git a/src/main/java/com/seibel/lod/core/a7/io/file/DataMetaFile.java b/src/main/java/com/seibel/lod/core/a7/io/file/DataMetaFile.java index ac4781df8..1b6a3f3b3 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/file/DataMetaFile.java +++ b/src/main/java/com/seibel/lod/core/a7/io/file/DataMetaFile.java @@ -17,7 +17,7 @@ import com.seibel.lod.core.a7.datatype.full.FullDatatype; import com.seibel.lod.core.a7.io.MetaFile; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.datatype.column.DataSourceSaver; import com.seibel.lod.core.a7.datatype.column.OldDataSourceLoader; import com.seibel.lod.core.util.LodUtil; diff --git a/src/main/java/com/seibel/lod/core/a7/io/DataSourceProvider.java b/src/main/java/com/seibel/lod/core/a7/io/file/DataSourceProvider.java similarity index 91% rename from src/main/java/com/seibel/lod/core/a7/io/DataSourceProvider.java rename to src/main/java/com/seibel/lod/core/a7/io/file/DataSourceProvider.java index 17718105f..f5b615c02 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/DataSourceProvider.java +++ b/src/main/java/com/seibel/lod/core/a7/io/file/DataSourceProvider.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7.io; +package com.seibel.lod.core.a7.io.file; import com.seibel.lod.core.a7.data.LodDataSource; import com.seibel.lod.core.a7.datatype.full.FullDatatype; diff --git a/src/main/java/com/seibel/lod/core/a7/io/file/LocalDataFileHandler.java b/src/main/java/com/seibel/lod/core/a7/io/file/LocalDataFileHandler.java index ce1764f6f..3acbc4869 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/file/LocalDataFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/io/file/LocalDataFileHandler.java @@ -3,10 +3,9 @@ package com.seibel.lod.core.a7.io.file; import com.google.common.collect.HashMultimap; import com.seibel.lod.core.a7.data.LodDataSource; import com.seibel.lod.core.a7.datatype.full.FullDatatype; -import com.seibel.lod.core.a7.io.DataSourceProvider; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.util.LodUtil; import org.apache.logging.log4j.Logger; diff --git a/src/main/java/com/seibel/lod/core/a7/io/render/RenderFileHandler.java b/src/main/java/com/seibel/lod/core/a7/io/render/RenderFileHandler.java index 136981c76..a9063b284 100644 --- a/src/main/java/com/seibel/lod/core/a7/io/render/RenderFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/io/render/RenderFileHandler.java @@ -2,7 +2,7 @@ package com.seibel.lod.core.a7.io.render; import com.seibel.lod.core.a7.RenderDataProvider; import com.seibel.lod.core.a7.datatype.full.FullDatatype; -import com.seibel.lod.core.a7.io.DataSourceProvider; +import com.seibel.lod.core.a7.io.file.DataSourceProvider; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.a7.render.RenderDataSource; @@ -25,7 +25,6 @@ public class RenderFileHandler implements RenderDataProvider { this.renderCacheFolder = renderCacheFolder; } - @Override public CompletableFuture createRenderData(RenderDataSourceLoader renderSourceLoader, DhSectionPos pos) { return null; @@ -36,6 +35,6 @@ public class RenderFileHandler implements RenderDataProvider { } public void write(DhSectionPos sectionPos, FullDatatype chunkData) { - + ` } } diff --git a/src/main/java/com/seibel/lod/core/a7/io/render/RenderSourceProvider.java b/src/main/java/com/seibel/lod/core/a7/io/render/RenderSourceProvider.java new file mode 100644 index 000000000..17946860c --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/io/render/RenderSourceProvider.java @@ -0,0 +1,14 @@ +package com.seibel.lod.core.a7.io.render; + +import com.seibel.lod.core.a7.data.LodDataSource; +import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.pos.DhSectionPos; +import com.seibel.lod.core.a7.render.RenderDataSource; + +import java.util.concurrent.CompletableFuture; + +public interface RenderSourceProvider { + CompletableFuture get(DhSectionPos pos); + void write(DhSectionPos sectionPos, FullDatatype chunkData); + CompletableFuture flushAndSave(); +} diff --git a/src/main/java/com/seibel/lod/core/a7/DHLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DHLevel.java similarity index 90% rename from src/main/java/com/seibel/lod/core/a7/DHLevel.java rename to src/main/java/com/seibel/lod/core/a7/level/DHLevel.java index 6a2c5e53f..dbec7dc16 100644 --- a/src/main/java/com/seibel/lod/core/a7/DHLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DHLevel.java @@ -1,5 +1,8 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.level; +import com.seibel.lod.core.a7.world.DhWorld; +import com.seibel.lod.core.a7.LodQuadTree; +import com.seibel.lod.core.a7.RenderDataProvider; import com.seibel.lod.core.a7.data.DataFileHandler; import com.seibel.lod.core.a7.pos.DhBlockPos2D; import com.seibel.lod.core.a7.render.RenderBufferHandler; @@ -11,7 +14,7 @@ import com.seibel.lod.core.util.EventLoop; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import java.io.Closeable; import java.io.File; @@ -25,13 +28,12 @@ public class DHLevel extends LodQuadTree implements Closeable { public final RenderBufferHandler renderBufferHandler; public final ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHLevelTickerThread", 2); private final AtomicBoolean isRunning = new AtomicBoolean(false); - public final IWorldWrapper level; + public final ILevelWrapper level; public a7LodRenderer renderer; - public final DHWorld world; - + public final DhWorld world; public EventLoop eventLoop; - public DHLevel(DHWorld world, File saveFolder, IWorldWrapper level) { + public DHLevel(DhWorld world, File saveFolder, ILevelWrapper level) { super(Config.Client.Graphics.Quality.lodChunkRenderDistance.get()*16, MC.getPlayerBlockPos().x, MC.getPlayerBlockPos().z); diff --git a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java b/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java index 29932af98..64efa9bb4 100644 --- a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java @@ -2,8 +2,8 @@ package com.seibel.lod.core.a7.render; import com.seibel.lod.core.a7.data.LodDataSource; import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.DHLevel; -import com.seibel.lod.core.objects.a7.data.DataFile; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.data.DataFile; import java.util.*; import java.util.stream.Collectors; diff --git a/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java b/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java new file mode 100644 index 000000000..c85e9456c --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java @@ -0,0 +1,174 @@ +package com.seibel.lod.core.a7.save.structure; + +import com.seibel.lod.core.a7.io.LevelToFileMatcher; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.world.DhClientWorld; +import com.seibel.lod.core.a7.world.DhWorld; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.enums.config.EServerFolderNameMode; +import com.seibel.lod.core.enums.config.EVerticalQuality; +import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.objects.ParsedIp; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +import javax.annotation.Nullable; +import java.io.File; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ClientOnlySaveStructure extends SaveStructure { + final File folder; + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); + public static final String INVALID_FILE_CHARACTERS_REGEX = "[\\\\/:*?\"<>|]"; + private static String getServerFolderName() + { + // parse the current server's IP + ParsedIp parsedIp = new ParsedIp(MC_CLIENT.getCurrentServerIp()); + String serverIpCleaned = parsedIp.ip.replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + String serverPortCleaned = parsedIp.port != null ? parsedIp.port.replaceAll(INVALID_FILE_CHARACTERS_REGEX, "") : ""; + + // determine the format of the folder name + EServerFolderNameMode folderNameMode = Config.Client.Multiplayer.serverFolderNameMode.get(); + if (folderNameMode == EServerFolderNameMode.AUTO) + { + if (parsedIp.isLan()) + { + // LAN + folderNameMode = EServerFolderNameMode.NAME_IP; + } + else + { + // normal multiplayer + folderNameMode = EServerFolderNameMode.NAME_IP_PORT; + } + } + String serverName = MC_CLIENT.getCurrentServerName().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + String serverMcVersion = MC_CLIENT.getCurrentServerVersion().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + // generate the folder name + String folderName = ""; + switch (folderNameMode) + { + // default and auto shouldn't be used + // and are just here to make the compiler happy + default: + case NAME_ONLY: + folderName = serverName; + break; + + case NAME_IP: + folderName = serverName + ", IP " + serverIpCleaned; + break; + case NAME_IP_PORT: + folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : ""); + break; + case NAME_IP_PORT_MC_VERSION: + folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "") + ", GameVersion " + serverMcVersion; + break; + } + return folderName; + } + + LevelToFileMatcher fileMatcher = null; + final DhClientWorld world; + + // Fit for Client_Only environment + public ClientOnlySaveStructure(DhClientWorld world) { + folder = new File(MC_CLIENT.getGameDirectory().getPath() + + File.separatorChar + "Distant_Horizons_server_data" + File.separatorChar + getServerFolderName()); + if (!folder.exists()) folder.mkdirs(); //TODO: Deal with errors + this.world = world; + } + + @Override + public DHLevel tryGetLevel(ILevelWrapper wrapper) { + if (Config.Client.Multiplayer.multiDimensionRequiredSimilarity.get() == 0) { + if (fileMatcher != null) { + fileMatcher.close(); + fileMatcher = null; + } + return new DHLevel(world, getLevelFolderWithoutSimilarityMatching(wrapper), wrapper); + } + + if (fileMatcher == null || !fileMatcher.isFindingLevel(wrapper)) { + LOGGER.info("Loading level for world " + wrapper.getDimensionType().getDimensionName()); + fileMatcher = new LevelToFileMatcher(world, wrapper, folder, + (File[]) getMatchingLevelFolders(wrapper).toArray()); + } + + DHLevel level = fileMatcher.tryGetLevel(); + if (level != null) { + fileMatcher.close(); + fileMatcher = null; + } + return level; + } + + private File getLevelFolderWithoutSimilarityMatching(ILevelWrapper level) + { + Stream folders = getMatchingLevelFolders(level); + Optional first = folders.findFirst(); + if (first.isPresent()) + { + LOGGER.info("Default Sub Dimension set to: [" + LodUtil.shortenString(first.get().getName(), 8) + "...]"); + return first.get(); + } else { // if no valid sub dimension was found, create a new one + LOGGER.info("Default Sub Dimension not found. Creating: [" + level.getDimensionType().getDimensionName() + "]"); + return new File(folder, level.getDimensionType().getDimensionName()); + } + } + + public Stream getMatchingLevelFolders(@Nullable ILevelWrapper level) { + File[] folders = folder.listFiles(); + if (folders==null) return Stream.empty(); + return Arrays.stream(folders).filter( + (f) -> { + if (!isValidLevelFolder(f)) return false; + return level==null || f.getName().equalsIgnoreCase(level.getDimensionType().getDimensionName()); + } + ).sorted(); + } + + /** Returns true if the given folder holds valid Lod Dimension data */ + private static boolean isValidLevelFolder(File potentialFolder) + { + if (!potentialFolder.isDirectory()) + // it needs to be a folder + return false; + + if (potentialFolder.listFiles() == null) + // it needs to have folders in it + return false; + + // check if there is at least one VerticalQuality folder in this directory + for (File internalFolder : potentialFolder.listFiles()) + { + if (EVerticalQuality.getByName(internalFolder.getName()) != null) + { + // one of the internal folders is a VerticalQuality folder + return true; + } + } + + return false; + } + + + @Override + public File getRenderCacheFolder(ILevelWrapper world) { + return null; + } + + @Override + public File getDataFolder(ILevelWrapper world) { + return null; + } + + @Override + public void close() { + fileMatcher.close(); + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java b/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java new file mode 100644 index 000000000..5a27da3fd --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java @@ -0,0 +1,29 @@ +package com.seibel.lod.core.a7.save.structure; + +import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +import java.io.File; + +public class LocalSaveStructure extends SaveStructure { + private static final IMinecraftSharedWrapper MC = SingletonHandler.get(IMinecraftSharedWrapper.class); + + private final File folder; + + // Fit for Client_Server & Server_Only environment + public LocalSaveStructure() { + folder = MC.getInstallationDirectory(); + } + + @Override + public File getRenderCacheFolder(ILevelWrapper world) { + return null; + } + + @Override + public File getDataFolder(ILevelWrapper world) { + return null; + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/save/structure/SaveStructure.java b/src/main/java/com/seibel/lod/core/a7/save/structure/SaveStructure.java new file mode 100644 index 000000000..5824c18ad --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/save/structure/SaveStructure.java @@ -0,0 +1,21 @@ +package com.seibel.lod.core.a7.save.structure; + +import com.seibel.lod.core.a7.io.LevelToFileMatcher; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.logging.DhLoggerBuilder; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; +import org.apache.logging.log4j.Logger; + +import java.io.File; + +public abstract class SaveStructure implements AutoCloseable { + + protected static final Logger LOGGER = DhLoggerBuilder.getLogger(); + + public abstract DHLevel tryGetLevel(ILevelWrapper wrapper); + + protected abstract File getRenderCacheFolder(ILevelWrapper world); + protected abstract File getDataFolder(ILevelWrapper world); +} + diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java new file mode 100644 index 000000000..e74500418 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java @@ -0,0 +1,85 @@ +package com.seibel.lod.core.a7.world; + +import com.seibel.lod.core.a7.WorldEnvironment; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.util.DetailDistanceUtil; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +import java.util.HashMap; +import java.util.Iterator; + +public class DhClientServerWorld extends DhWorld implements IClientWorld, IServerWorld { + private final HashMap levels; + public final LocalSaveStructure saveStructure; + + public DhClientServerWorld() { + super(WorldEnvironment.Client_Server); + saveStructure = new LocalSaveStructure(); + levels = new HashMap<>(); + } + + @Override + public DHLevel getOrLoadLevel(ILevelWrapper wrapper) { + if (!levels.containsKey(wrapper)) { + DHLevel level = saveStructure.tryGetLevel(wrapper); + if (level != null) { + levels.put(wrapper, level); + } + return level; + } else return levels.get(wrapper); + } + + @Override + public DHLevel getLevel(ILevelWrapper wrapper) { + return levels.get(wrapper); + } + + @Override + public void unloadLevel(ILevelWrapper wrapper) { + if (levels.containsKey(wrapper)) { + LOGGER.info("Unloading level for world " + wrapper.getDimensionType().getDimensionName()); + levels.get(wrapper).close(); + levels.remove(wrapper).close(); + } + } + + public void tick() { + int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * 16; + Iterator iterator = levels.values().iterator(); + while (iterator.hasNext()) { + DHLevel level = iterator.next(); + if (level.viewDistance != newViewDistance) { + level.close(); + iterator.remove(); + } + } + DetailDistanceUtil.updateSettings(); + } + + public void doWorldGen() { + + } + + @Override + public void saveAndFlush() { + for (DHLevel level : levels.values()) { + level.saveFlush(); + } + } + + @Override + public void close() { + for (DHLevel level : levels.values()) { + LOGGER.info("Unloading level for world " + level.level.getDimensionType().getDimensionName()); + level.close(); + } + levels.clear(); + } + + @Override + public void render() { + + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/DHWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java similarity index 56% rename from src/main/java/com/seibel/lod/core/a7/DHWorld.java rename to src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java index 53f54e00d..af48bd2f8 100644 --- a/src/main/java/com/seibel/lod/core/a7/DHWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java @@ -1,67 +1,60 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.world; -import com.seibel.lod.core.a7.io.DHFolderHandler; +import com.seibel.lod.core.a7.WorldEnvironment; import com.seibel.lod.core.a7.io.LevelToFileMatcher; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.save.structure.ClientOnlySaveStructure; +import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.EventLoop; import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; -import org.apache.logging.log4j.Logger; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; -import java.io.Closeable; -import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.ExecutorService; -public class DHWorld implements Closeable { - private static final Logger LOGGER = DhLoggerBuilder.getLogger("DHWorld"); +public class DhClientWorld extends DhWorld implements IClientWorld { - private final File saveDir; - private final HashMap levels; - private LevelToFileMatcher levelToFileMatcher = null; + private final HashMap levels; + public final ClientOnlySaveStructure saveStructure; public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2); public EventLoop eventLoop = new EventLoop(dhTickerThread, this::tick); - public DHWorld() { - //Note: this changes the singleplayer lod save location. - saveDir = DHFolderHandler.getCurrentWorldFolder(); + public DhClientWorld() { + super(WorldEnvironment.Client_Only); + saveStructure = new ClientOnlySaveStructure(this); levels = new HashMap<>(); } - public DHLevel getOrLoadLevel(IWorldWrapper wrapper) { + @Override + public DHLevel getOrLoadLevel(ILevelWrapper wrapper) { if (!levels.containsKey(wrapper)) { - if (levelToFileMatcher == null || levelToFileMatcher.getTargetWorld() != wrapper) { - LOGGER.info("Loading level for world " + wrapper.getDimensionType().getDimensionName()); - levelToFileMatcher = new LevelToFileMatcher(this, saveDir, wrapper); - } - DHLevel level = levelToFileMatcher.tryGetLevel(); + DHLevel level = saveStructure.tryGetLevel(wrapper); if (level != null) { levels.put(wrapper, level); - levelToFileMatcher = null; - return level; - } else { - return null; } + return level; } else return levels.get(wrapper); } - public DHLevel getLevel(IWorldWrapper wrapper) { + @Override + public DHLevel getLevel(ILevelWrapper wrapper) { return levels.get(wrapper); } - public void unloadLevel(IWorldWrapper wrapper) { + @Override + public void unloadLevel(ILevelWrapper wrapper) { if (levels.containsKey(wrapper)) { LOGGER.info("Unloading level for world " + wrapper.getDimensionType().getDimensionName()); levels.get(wrapper).close(); - levels.remove(wrapper); + levels.remove(wrapper).close(); } } - public void tick() { + private void tick() { int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * 16; Iterator iterator = levels.values().iterator(); while (iterator.hasNext()) { @@ -73,13 +66,13 @@ public class DHWorld implements Closeable { } DetailDistanceUtil.updateSettings(); } - public void doWorldGen() { - } + public void asyncTick() { eventLoop.tick(); } - public void save() { + @Override + public void saveAndFlush() { for (DHLevel level : levels.values()) { level.saveFlush(); } @@ -94,4 +87,9 @@ public class DHWorld implements Closeable { } levels.clear(); } + + @Override + public void render() { + + } } diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java new file mode 100644 index 000000000..f10b07eee --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java @@ -0,0 +1,85 @@ +package com.seibel.lod.core.a7.world; + +import com.seibel.lod.core.a7.WorldEnvironment; +import com.seibel.lod.core.a7.io.LevelToFileMatcher; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.save.structure.ClientOnlySaveStructure; +import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.util.DetailDistanceUtil; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +import java.util.HashMap; +import java.util.Iterator; + +public class DhServerWorld extends DhWorld implements IServerWorld { + private final HashMap levels; + public final LocalSaveStructure saveStructure; + + public DhServerWorld() { + super(WorldEnvironment.Server_Only); + saveStructure = new LocalSaveStructure(); + levels = new HashMap<>(); + } + + @Override + public DHLevel getOrLoadLevel(ILevelWrapper wrapper) { + if (!levels.containsKey(wrapper)) { + DHLevel level = saveStructure.tryGetLevel(wrapper); + if (level != null) { + levels.put(wrapper, level); + } + return level; + } else return levels.get(wrapper); + } + + @Override + public DHLevel getLevel(ILevelWrapper wrapper) { + return levels.get(wrapper); + } + + @Override + public void unloadLevel(ILevelWrapper wrapper) { + if (levels.containsKey(wrapper)) { + LOGGER.info("Unloading level for world " + wrapper.getDimensionType().getDimensionName()); + levels.get(wrapper).close(); + levels.remove(wrapper).close(); + } + } + + public void tick() { + int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * 16; + Iterator iterator = levels.values().iterator(); + while (iterator.hasNext()) { + DHLevel level = iterator.next(); + if (level.viewDistance != newViewDistance) { + level.close(); + iterator.remove(); + } + } + DetailDistanceUtil.updateSettings(); + } + + public void doWorldGen() { + + } + + @Override + public void saveAndFlush() { + for (DHLevel level : levels.values()) { + level.saveFlush(); + } + } + + @Override + public void close() { + for (DHLevel level : levels.values()) { + LOGGER.info("Unloading level for world " + level.level.getDimensionType().getDimensionName()); + level.close(); + } + levels.clear(); + } + + + +} diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java new file mode 100644 index 000000000..356f45e7c --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java @@ -0,0 +1,34 @@ +package com.seibel.lod.core.a7.world; + +import com.seibel.lod.core.a7.WorldEnvironment; +import com.seibel.lod.core.a7.io.LevelToFileMatcher; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.save.structure.SaveStructure; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.logging.DhLoggerBuilder; +import com.seibel.lod.core.util.DetailDistanceUtil; +import com.seibel.lod.core.util.EventLoop; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; +import org.apache.logging.log4j.Logger; + +import java.io.Closeable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.concurrent.ExecutorService; + +public abstract class DhWorld implements Closeable { + protected static final Logger LOGGER = DhLoggerBuilder.getLogger(); + + public final WorldEnvironment environment; + + protected DhWorld(WorldEnvironment environment) { + this.environment = environment; + } + public abstract DHLevel getOrLoadLevel(ILevelWrapper wrapper); + + public abstract DHLevel getLevel(ILevelWrapper wrapper); + + public abstract void unloadLevel(ILevelWrapper wrapper); + public abstract void saveAndFlush(); +} diff --git a/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java b/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java new file mode 100644 index 000000000..9b639d059 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java @@ -0,0 +1,5 @@ +package com.seibel.lod.core.a7.world; + +public interface IClientWorld { + void render(); +} diff --git a/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java new file mode 100644 index 000000000..368c2da64 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java @@ -0,0 +1,5 @@ +package com.seibel.lod.core.a7.world; + +public interface IServerWorld { + void doWorldGen(); +} diff --git a/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java b/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java index 74d8b2c07..914a0e428 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java @@ -30,6 +30,7 @@ import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.render.RenderSystemTest; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Level; import com.seibel.lod.core.handlers.LodDimensionFinder; import org.apache.logging.log4j.LogManager; @@ -51,7 +52,6 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; /** * This holds the methods that should be called @@ -142,7 +142,7 @@ public class ClientApi private final ConcurrentHashMap.KeySetView generating = ConcurrentHashMap.newKeySet(); public final ConcurrentHashMap.KeySetView toBeLoaded = ConcurrentHashMap.newKeySet(); - public void clientChunkLoadEvent(IChunkWrapper chunk, IWorldWrapper world) + public void clientChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper world) { LagSpikeCatcher clientChunkLoad = new LagSpikeCatcher(); //ApiShared.LOGGER.info("Lod Generating add: "+chunk.getLongChunkPos()); @@ -187,7 +187,7 @@ public class ClientApi if (!MC.playerExists() || InternalApiShared.lodWorld.getIsWorldNotLoaded()) return; - IWorldWrapper world = MC.getWrappedClientWorld(); + ILevelWrapper world = MC.getWrappedClientWorld(); if (world == null) return; LodDimension lodDim = InternalApiShared.lodWorld.getLodDimension(world.getDimensionType()); diff --git a/src/main/java/com/seibel/lod/core/api/internal/EventApi.java b/src/main/java/com/seibel/lod/core/api/internal/EventApi.java index 972585174..c13a2cf01 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/EventApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/EventApi.java @@ -36,7 +36,7 @@ import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Logger; import java.lang.invoke.MethodHandles; @@ -124,7 +124,7 @@ public class EventApi } /** This is also called when a new dimension loads */ - public void worldLoadEvent(IWorldWrapper world) + public void worldLoadEvent(ILevelWrapper world) { if (ENABLE_STACK_DUMP_LOGGING) LOGGER.info( @@ -157,7 +157,7 @@ public class EventApi } /** This is also called when the user disconnects from a server+ */ - public void worldUnloadEvent(IWorldWrapper world) + public void worldUnloadEvent(ILevelWrapper world) { if (ENABLE_STACK_DUMP_LOGGING) LOGGER.info( diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java index 0dfacd3f4..22513036d 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java @@ -27,8 +27,8 @@ import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.logging.SpamReducedLogger; -import com.seibel.lod.core.a7.DHLevel; -import com.seibel.lod.core.a7.DHWorld; +import com.seibel.lod.core.a7.level.DHLevel; +import com.seibel.lod.core.a7.world.DhWorld; import com.seibel.lod.core.a7.Server; import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.render.GLProxy; @@ -37,7 +37,7 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -116,7 +116,7 @@ public class ClientApi public void clientServerConnected() { SharedApi.currentServer = new Server(false); - SharedApi.currentWorld = new DHWorld(); + SharedApi.currentWorld = new DhWorld(enviroment); } public void clientServerDisconnected() { SharedApi.currentWorld.close(); @@ -124,22 +124,22 @@ public class ClientApi SharedApi.currentServer = null; } - public void clientChunkLoadEvent(IChunkWrapper chunk, IWorldWrapper world) + public void clientChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper world) { //TODO: Implement } - public void clientChunkSaveEvent(IChunkWrapper chunk, IWorldWrapper world) + public void clientChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) { //TODO: Implement } - public void clientLevelUnloadEvent(IWorldWrapper world) + public void clientLevelUnloadEvent(ILevelWrapper world) { if (SharedApi.currentWorld != null) { SharedApi.currentWorld.unloadLevel(world); } } - public void clientLevelLoadEvent(IWorldWrapper world) + public void clientLevelLoadEvent(ILevelWrapper world) { //TODO: Maybe make DHLevel init no longer depend on needing player entity in single player if (SharedApi.currentWorld != null) { @@ -189,7 +189,7 @@ public class ClientApi profiler.pop(); } - public void renderLods(IWorldWrapper world, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) + public void renderLods(ILevelWrapper world, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) { IProfilerWrapper profiler = MC.getProfiler(); profiler.pop(); // get out of "terrain" @@ -197,9 +197,9 @@ public class ClientApi try { if (!MC.playerExists()) return; if (world == null) return; - DHWorld dhWorld = SharedApi.currentWorld; - if (dhWorld == null) return; - DHLevel level = (SharedApi.currentServer == null) ? dhWorld.getOrLoadLevel(world) : dhWorld.getLevel(world); + DhWorld DhWorld = SharedApi.currentWorld; + if (DhWorld == null) return; + DHLevel level = (SharedApi.currentServer == null) ? DhWorld.getOrLoadLevel(world) : DhWorld.getLevel(world); if (level == null) return; if (prefLoggerEnabled) { diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java index e034d35d3..730ba36ea 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java @@ -21,11 +21,11 @@ package com.seibel.lod.core.api.internal.a7; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.DHWorld; +import com.seibel.lod.core.a7.world.DhWorld; import com.seibel.lod.core.a7.Server; import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Logger; import java.lang.invoke.MethodHandles; @@ -60,15 +60,15 @@ public class ServerApi lastWorldGenTickDelta--; if (SharedApi.currentWorld != null && lastWorldGenTickDelta <= 0) { lastWorldGenTickDelta = 20; - DHWorld dhWorld = SharedApi.currentWorld; - dhWorld.tick(); + DhWorld DhWorld = SharedApi.currentWorld; + DhWorld.tick(); } } //TODO: rename to serverLoadEvent public void serverWorldLoadEvent() { SharedApi.currentServer = new Server(!SharedApi.inDedicatedEnvironment); - SharedApi.currentWorld = new DHWorld(); + SharedApi.currentWorld = new DhWorld(enviroment); //TODO: Setup the network handler } @@ -80,12 +80,12 @@ public class ServerApi SharedApi.currentServer = null; } - public void serverLevelLoadEvent(IWorldWrapper world) { + public void serverLevelLoadEvent(ILevelWrapper world) { //TODO: Maybe make DHLevel init no longer depend on needing player entity in single player if (SharedApi.currentServer.isSinglePlayer) return; SharedApi.currentWorld.getOrLoadLevel(world); } - public void serverLevelUnloadEvent(IWorldWrapper world) { + public void serverLevelUnloadEvent(ILevelWrapper world) { SharedApi.currentWorld.unloadLevel(world); } @@ -96,12 +96,12 @@ public class ServerApi - public void chunkSaveEvent(IChunkWrapper chunk, IWorldWrapper world) { + public void chunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) { //TODO } - public void serverChunkLoadEvent(IChunkWrapper chunk, IWorldWrapper world) { + public void serverChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper world) { } - public void serverChunkSaveEvent(IChunkWrapper chunk, IWorldWrapper world) { + public void serverChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) { } } diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java index 2bc284909..ef78a8a80 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java @@ -1,13 +1,13 @@ package com.seibel.lod.core.api.internal.a7; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.DHWorld; +import com.seibel.lod.core.a7.world.DhWorld; import com.seibel.lod.core.a7.Server; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import org.apache.logging.log4j.Logger; public class SharedApi { - public static DHWorld currentWorld; + public static DhWorld currentWorld; public static Server currentServer; public static IMinecraftSharedWrapper MC; public static Logger LOGGER = DhLoggerBuilder.getLogger("DH Events"); diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 8ed1efc2f..80a777b56 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -43,7 +43,7 @@ import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.LogManager; /** @@ -493,7 +493,7 @@ public class LodBuilder if (blockLight == -1 || skyLight == -1) { - IWorldWrapper world = MC.getWrappedServerWorld(); + ILevelWrapper world = MC.getWrappedServerWorld(); if (world != null) { diff --git a/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java b/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java index 18d526890..6a1a1894b 100644 --- a/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java +++ b/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java @@ -31,7 +31,7 @@ import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps; import org.apache.logging.log4j.Logger; @@ -54,7 +54,7 @@ public class BatchGenerator private int estimatedPointsToQueue = 1; public BatchGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension) { - IWorldWrapper world = LodUtil.getServerWorldFromDimension(newLodDimension.dimension); + ILevelWrapper world = LodUtil.getServerWorldFromDimension(newLodDimension.dimension); targetLodDim = newLodDimension; generationGroup = FACTORY.createBatchGenerator(newLodBuilder, newLodDimension, world); MC.sendChatMessage("NOTE: You are currently using Distant Horizon's Batch Chunk Pre-Generator."); @@ -65,7 +65,7 @@ public class BatchGenerator public void queueGenerationRequests(LodDimension lodDim, LodBuilder lodBuilder) { if (lodDim != targetLodDim) { stop(false); - IWorldWrapper dim = LodUtil.getServerWorldFromDimension(lodDim.dimension); + ILevelWrapper dim = LodUtil.getServerWorldFromDimension(lodDim.dimension); generationGroup = FACTORY.createBatchGenerator(lodBuilder, lodDim, dim); targetLodDim = lodDim; LOGGER.info("1.18 Experimental Chunk Generator reinitialized"); diff --git a/src/main/java/com/seibel/lod/core/handlers/LodDimensionFinder.java b/src/main/java/com/seibel/lod/core/handlers/LodDimensionFinder.java index 1ee4497c3..59323b08b 100644 --- a/src/main/java/com/seibel/lod/core/handlers/LodDimensionFinder.java +++ b/src/main/java/com/seibel/lod/core/handlers/LodDimensionFinder.java @@ -41,7 +41,7 @@ import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.LogManager; import java.io.File; @@ -437,7 +437,7 @@ public class LodDimensionFinder { // local world - IWorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(newDimensionType); + ILevelWrapper serverWorld = LodUtil.getServerWorldFromDimension(newDimensionType); return new File(serverWorld.getSaveFolder().getCanonicalFile().getPath() + File.separatorChar + "lod" + File.separatorChar + worldId); } else diff --git a/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java b/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java index 0b1117923..cf3b74f40 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java +++ b/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java @@ -25,7 +25,9 @@ import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.objects.DHBlockPos; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import org.lwjgl.system.CallbackI; +import javax.annotation.Nullable; import java.io.File; /** @@ -55,10 +57,18 @@ public class PlayerData * I'm not sure what this will look like for worlds that don't have a spawn point. */ public DHBlockPos worldSpawnPointBlockPos; + @Nullable + public static PlayerData tryGetPlayerData(IMinecraftClientWrapper mcClient) { + if (!mcClient.playerExists()) return null; + try { + return new PlayerData(mcClient); + } catch (RuntimeException e) { + // Player no longer exists due to concurrency. FIXME: Remember here is called not on main thread!!! + return null; + } + } - - - public PlayerData(IMinecraftClientWrapper mc) + private PlayerData(IMinecraftClientWrapper mc) { updateData(mc); } @@ -66,24 +76,23 @@ public class PlayerData public PlayerData(File dimensionFolder) { File file = getFileForDimensionFolder(dimensionFolder); - CommentedFileConfig toml = CommentedFileConfig.builder(file).build(); - - toml.load(); - - - // get the player block pos if it is specified - if (toml.contains(PLAYER_BLOCK_POS_X_PATH) - && toml.contains(PLAYER_BLOCK_POS_Y_PATH) - && toml.contains(PLAYER_BLOCK_POS_Z_PATH)) - { - int x = toml.getIntOrElse(PLAYER_BLOCK_POS_X_PATH, 0); - int y = toml.getIntOrElse(PLAYER_BLOCK_POS_Y_PATH, 0); - int z = toml.getIntOrElse(PLAYER_BLOCK_POS_Z_PATH, 0); - this.playerBlockPos = new DHBlockPos(x, y, z); - } - else - { - this.playerBlockPos = new DHBlockPos(0, 0, 0); + try (CommentedFileConfig toml = CommentedFileConfig.builder(file).build()) { + toml.load(); + + // get the player block pos if it is specified + if (toml.contains(PLAYER_BLOCK_POS_X_PATH) + && toml.contains(PLAYER_BLOCK_POS_Y_PATH) + && toml.contains(PLAYER_BLOCK_POS_Z_PATH)) + { + int x = toml.getIntOrElse(PLAYER_BLOCK_POS_X_PATH, 0); + int y = toml.getIntOrElse(PLAYER_BLOCK_POS_Y_PATH, 0); + int z = toml.getIntOrElse(PLAYER_BLOCK_POS_Z_PATH, 0); + this.playerBlockPos = new DHBlockPos(x, y, z); + } + else + { + this.playerBlockPos = new DHBlockPos(0, 0, 0); + } } } @@ -98,10 +107,8 @@ public class PlayerData /** Should be called often to make sure this object is up to date with the player's info */ public void updateData(IMinecraftClientWrapper mc) { - if (mc.playerExists()) - { - this.playerBlockPos = mc.getPlayerBlockPos(); - } + this.playerBlockPos = mc.getPlayerBlockPos(); + if (playerBlockPos == null) throw new RuntimeException("No player block pos!"); } /** Writes everything from this object to the file given. */ diff --git a/src/main/java/com/seibel/lod/core/logging/DhLoggerBuilder.java b/src/main/java/com/seibel/lod/core/logging/DhLoggerBuilder.java index de759d173..5d4be92f3 100644 --- a/src/main/java/com/seibel/lod/core/logging/DhLoggerBuilder.java +++ b/src/main/java/com/seibel/lod/core/logging/DhLoggerBuilder.java @@ -31,4 +31,22 @@ public class DhLoggerBuilder { return LogManager.getLogger(ModInfo.NAME + "-" + className); } + public static Logger getLogger(Class clazz) + { + return LogManager.getLogger(ModInfo.NAME + "-" + clazz.getSimpleName()); + } + public static Logger getLogger() + { + StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); + String callerClassName = "??"; + for (int i=1; i @@ -526,7 +526,7 @@ public class LodRenderer // returns whether anything changed private boolean updateVanillaRenderedChunks(LodDimension lodDim) { // if the player is high enough, draw all LODs - IWorldWrapper world = MC.getWrappedClientWorld(); + ILevelWrapper world = MC.getWrappedClientWorld(); if (lastUpdatedPos.getY() > world.getHeight()-world.getMinHeight() || Config.Client.Advanced.lodOnlyMode.get()) { if (vanillaChunks != null) { diff --git a/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java b/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java index ca22c7efc..4ebc506c1 100644 --- a/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java +++ b/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java @@ -28,7 +28,7 @@ import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.objects.DHBlockPos; -import com.seibel.lod.core.a7.DHLevel; +import com.seibel.lod.core.a7.level.DHLevel; import com.seibel.lod.core.a7.render.RenderBufferHandler; import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.objects.math.Vec3d; diff --git a/src/main/java/com/seibel/lod/core/util/LodUtil.java b/src/main/java/com/seibel/lod/core/util/LodUtil.java index 2943b1181..4c312b696 100644 --- a/src/main/java/com/seibel/lod/core/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/core/util/LodUtil.java @@ -42,7 +42,7 @@ import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; /** * This class holds methods and constants that may be used in multiple places. @@ -165,15 +165,15 @@ public class LodUtil * Gets the ServerWorld for the relevant dimension. * @return null if there is no ServerWorld for the given dimension */ - public static IWorldWrapper getServerWorldFromDimension(IDimensionTypeWrapper newDimension) + public static ILevelWrapper getServerWorldFromDimension(IDimensionTypeWrapper newDimension) { if(!MC.hasSinglePlayerServer()) return null; - Iterable worlds = MC.getAllServerWorlds(); - IWorldWrapper returnWorld = null; + Iterable worlds = MC.getAllServerWorlds(); + ILevelWrapper returnWorld = null; - for (IWorldWrapper world : worlds) + for (ILevelWrapper world : worlds) { if (world.getDimensionType() == newDimension) { @@ -200,7 +200,7 @@ public class LodUtil * world, if in multiplayer it will return the server name, IP, * and game version. */ - public static String getWorldID(IWorldWrapper world) + public static String getWorldID(ILevelWrapper world) { if (MC.hasSinglePlayerServer()) { @@ -229,14 +229,14 @@ public class LodUtil * dimension. */ @Deprecated // FIXME: There are soooo many duplicated methods doing the same thing everywhere - public static String getDimensionIDFromWorld(IWorldWrapper world) + public static String getDimensionIDFromWorld(ILevelWrapper world) { if (MC.hasSinglePlayerServer()) { // this will return the world save location // and the dimension folder - IWorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(world.getDimensionType()); + ILevelWrapper serverWorld = LodUtil.getServerWorldFromDimension(world.getDimensionType()); if (serverWorld == null) throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the WorldWrapper for the dimension " + world.getDimensionType().getDimensionName()); diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java index 182c02d9d..d717e3138 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java @@ -21,10 +21,8 @@ package com.seibel.lod.core.wrapperInterfaces; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.handlers.dependencyInjection.IBindable; -import com.seibel.lod.core.objects.DHBlockPos; -import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.objects.lod.LodDimension; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper; /** @@ -36,5 +34,5 @@ import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenera public interface IWrapperFactory extends IBindable { AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder, - LodDimension newLodDimension, IWorldWrapper worldWrapper); + LodDimension newLodDimension, ILevelWrapper worldWrapper); } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java index c99241d24..6ae3de528 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java @@ -27,7 +27,7 @@ import com.seibel.lod.core.handlers.dependencyInjection.IBindable; import com.seibel.lod.core.objects.DHBlockPos; import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; /** * Contains everything related to the Minecraft object. @@ -86,9 +86,9 @@ public interface IMinecraftClientWrapper extends IBindable * the user is currently in. * @return null if no ServerWorld is available */ - IWorldWrapper getWrappedServerWorld(); + ILevelWrapper getWrappedServerWorld(); - IWorldWrapper getWrappedClientWorld(); + ILevelWrapper getWrappedClientWorld(); File getGameDirectory(); @@ -101,7 +101,7 @@ public interface IMinecraftClientWrapper extends IBindable int getPlayerSkylight(); /** Returns all worlds available to the server */ - ArrayList getAllServerWorlds(); + ArrayList getAllServerWorlds(); diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java index 4680ac505..bf6671583 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java @@ -34,7 +34,7 @@ import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; /** * Contains everything related to @@ -105,7 +105,7 @@ public interface IMinecraftRenderWrapper extends IBindable IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class); IVersionConstants versionConstants = SingletonHandler.get(IVersionConstants.class); IMinecraftClientWrapper minecraft = SingletonHandler.get(IMinecraftClientWrapper.class); - IWorldWrapper clientWorld = minecraft.getWrappedClientWorld(); + ILevelWrapper clientWorld = minecraft.getWrappedClientWorld(); int chunkDist = this.getRenderDistance() + 1; // For some reason having '+1' is actually closer to real value diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java index 146e18a89..3e69e4711 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java @@ -1,7 +1,12 @@ package com.seibel.lod.core.wrapperInterfaces.minecraft; -public interface IMinecraftSharedWrapper { - boolean isServerJar(); +import com.seibel.lod.core.handlers.dependencyInjection.IBindable; +import java.io.File; + +//TODO: Maybe have IMCClientWrapper & IMCDedicatedWrapper extend this interface??? +public interface IMinecraftSharedWrapper extends IBindable { + boolean isServerJar(); + File getInstallationDirectory(); } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IBiomeColorWrapperSingleton.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IBiomeColorWrapperSingleton.java index 5dda6aa30..d0068d8cd 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IBiomeColorWrapperSingleton.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IBiomeColorWrapperSingleton.java @@ -33,7 +33,7 @@ public interface IBiomeColorWrapperSingleton extends IBindable { IBiomeColorWrapperSingleton getInstance(); - int getGrassColor(IWorldWrapper world, DHBlockPos blockPos); - int getWaterColor(IWorldWrapper world, DHBlockPos blockPos); - int getFoliageColor(IWorldWrapper world, DHBlockPos blockPos); + int getGrassColor(ILevelWrapper world, DHBlockPos blockPos); + int getWaterColor(ILevelWrapper world, DHBlockPos blockPos); + int getFoliageColor(ILevelWrapper world, DHBlockPos blockPos); } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IWorldWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java similarity index 97% rename from src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IWorldWrapper.java rename to src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java index e2888e180..c5bb15896 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IWorldWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java @@ -32,7 +32,7 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; * @author James Seibel * @version 3-5-2022 */ -public interface IWorldWrapper extends IBindable +public interface ILevelWrapper extends IBindable { IDimensionTypeWrapper getDimensionType(); diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/worldGeneration/AbstractBatchGenerationEnvionmentWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/worldGeneration/AbstractBatchGenerationEnvionmentWrapper.java index ada269acb..83803cbdd 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/worldGeneration/AbstractBatchGenerationEnvionmentWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/worldGeneration/AbstractBatchGenerationEnvionmentWrapper.java @@ -21,15 +21,15 @@ package com.seibel.lod.core.wrapperInterfaces.worldGeneration; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.objects.lod.LodDimension; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; public abstract class AbstractBatchGenerationEnvionmentWrapper { public static enum Steps { Empty, StructureStart, StructureReference, Biomes, Noise, Surface, Carvers, LiquidCarvers, Features, Light, } - public AbstractBatchGenerationEnvionmentWrapper(IWorldWrapper serverLevel, LodBuilder lodBuilder, - LodDimension lodDim) { + public AbstractBatchGenerationEnvionmentWrapper(ILevelWrapper serverLevel, LodBuilder lodBuilder, + LodDimension lodDim) { } public abstract void resizeThreadPool(int newThreadCount);