2nd Refactor started. Split to 3 type world structure
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package com.seibel.lod.core.a7;
|
||||
|
||||
public enum WorldEnvironment {
|
||||
Client_Only,
|
||||
Client_Server,
|
||||
Server_Only
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<RenderDataSource> createRenderData(RenderDataSourceLoader renderSourceLoader, DhSectionPos pos) {
|
||||
return null;
|
||||
@@ -36,6 +35,6 @@ public class RenderFileHandler implements RenderDataProvider {
|
||||
}
|
||||
|
||||
public void write(DhSectionPos sectionPos, FullDatatype chunkData) {
|
||||
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<RenderDataSource> get(DhSectionPos pos);
|
||||
void write(DhSectionPos sectionPos, FullDatatype chunkData);
|
||||
CompletableFuture<Void> flushAndSave();
|
||||
}
|
||||
+8
-6
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -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<File> folders = getMatchingLevelFolders(level);
|
||||
Optional<File> 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<File> 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<ILevelWrapper, DHLevel> 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<DHLevel> 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() {
|
||||
|
||||
}
|
||||
}
|
||||
+30
-32
@@ -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<IWorldWrapper, DHLevel> levels;
|
||||
private LevelToFileMatcher levelToFileMatcher = null;
|
||||
private final HashMap<ILevelWrapper, DHLevel> 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<DHLevel> 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() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<ILevelWrapper, DHLevel> 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<DHLevel> 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.seibel.lod.core.a7.world;
|
||||
|
||||
public interface IClientWorld {
|
||||
void render();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.seibel.lod.core.a7.world;
|
||||
|
||||
public interface IServerWorld {
|
||||
void doWorldGen();
|
||||
}
|
||||
@@ -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<DHChunkPos,Boolean> generating = ConcurrentHashMap.newKeySet();
|
||||
public final ConcurrentHashMap.KeySetView<DHChunkPos,Boolean> 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());
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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<stElements.length; i++) {
|
||||
StackTraceElement ste = stElements[i];
|
||||
if (!ste.getClassName().equals(DhLoggerBuilder.class.getName())
|
||||
&& ste.getClassName().indexOf("java.lang.Thread")!=0) {
|
||||
callerClassName = ste.getClassName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return LogManager.getLogger(ModInfo.NAME + "-" + callerClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.seibel.lod.core.render.objects.GLState;
|
||||
import com.seibel.lod.core.util.*;
|
||||
import com.seibel.lod.core.util.gridList.*;
|
||||
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
@@ -51,7 +52,6 @@ import com.seibel.lod.core.objects.opengl.RenderRegion;
|
||||
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 is where all the magic happens. <br>
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<IWorldWrapper> worlds = MC.getAllServerWorlds();
|
||||
IWorldWrapper returnWorld = null;
|
||||
Iterable<ILevelWrapper> 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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+4
-4
@@ -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<IWorldWrapper> getAllServerWorlds();
|
||||
ArrayList<ILevelWrapper> getAllServerWorlds();
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
|
||||
+7
-2
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user