Close !69 (add IDhApiLevelWrapper.getDhSaveFolder())

This commit is contained in:
James Seibel
2024-10-04 07:45:53 -05:00
parent 3fb4c254c1
commit 0b49d1a007
5 changed files with 49 additions and 84 deletions
@@ -23,6 +23,8 @@ import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
import java.io.File;
/**
* Can be either a Server or Client level.<br>
* A level is equivalent to a dimension in vanilla Minecraft.
@@ -72,4 +74,15 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper
*/
IDhApiCustomRenderRegister getRenderRegister();
/**
* Returns the folder Distant Horizons uses to save
* data associated with this level.
* Will return null if the level is not loaded.
*
* @since API 4.0.0
*/
File getDhSaveFolder();
}
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.core.file.structure;
import com.google.common.net.PercentEscaper;
import com.seibel.distanthorizons.api.interfaces.override.levelHandling.IDhApiSaveStructure;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.file.subDimMatching.SubDimensionLevelMatcher;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.api.enums.config.EDhApiServerFolderNameMode;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
@@ -30,7 +29,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.objects.ParsedIp;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import com.seibel.distanthorizons.coreapi.util.StringUtil;
@@ -38,6 +36,7 @@ import org.apache.logging.log4j.Logger;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Designed for the Client_Only environment.
@@ -54,8 +53,7 @@ public class ClientOnlySaveStructure implements ISaveStructure
private static final IMinecraftSharedWrapper MC_SHARED = SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class);
private final File folder;
private final HashMap<ILevelWrapper, File> levelWrapperToFileMap = new HashMap<>();
private final ConcurrentHashMap<ILevelWrapper, File> levelWrapperToFileMap = new ConcurrentHashMap<>();
@@ -63,21 +61,7 @@ public class ClientOnlySaveStructure implements ISaveStructure
// constructor //
//=============//
public ClientOnlySaveStructure()
{
this.folder = new File(getSaveStructureFolderPath());
if (!this.folder.exists())
{
if (!this.folder.mkdirs())
{
LOGGER.warn("Unable to create folder [" + this.folder.getPath() + "]");
//TODO: Deal with errors
}
}
}
public ClientOnlySaveStructure() { }
@@ -85,47 +69,6 @@ public class ClientOnlySaveStructure implements ISaveStructure
// folder methods //
//================//
private File getLevelFolderWithoutSimilarityMatching(ILevelWrapper level)
{
List<File> folders = this.getDhDataFoldersForLevel(level);
if (!folders.isEmpty() && folders.get(0) != null)
{
// use the first existing sub-dimension
String folderName = folders.get(0).getName();
LOGGER.info("Default Sub Dimension set to: [" + StringUtil.shortenString(folderName, 8) + "...]");
return folders.get(0);
}
else
{
// no valid sub dimension was found, create a new one
LOGGER.info("Default Sub Dimension not found. Creating: [" + level.getDimensionName() + "]");
return new File(this.folder, level.getDimensionName().replaceAll(":", "@@"));
}
}
public List<File> getDhDataFoldersForLevel(ILevelWrapper level)
{
File[] folders = this.folder.listFiles();
if (folders == null)
{
return new ArrayList<>(0);
}
// filter by dimension name
String expectedDimName = level.getDimensionName();
ArrayList<File> possibleDimFolders = new ArrayList<>();
for (File dimFolder : folders)
{
if (dimFolder.isDirectory() && dimFolder.getName().equals(expectedDimName))
{
possibleDimFolders.addAll(getValidDhDimensionFolders(dimFolder));
}
}
return possibleDimFolders;
}
@Override
public File getSaveFolder(ILevelWrapper levelWrapper)
{
@@ -139,12 +82,12 @@ public class ClientOnlySaveStructure implements ISaveStructure
IServerKeyedClientLevel keyedClientLevel = (IServerKeyedClientLevel) newLevelWrapper;
LOGGER.info("Loading level [" + newLevelWrapper.getDimensionName() + "] with key: [" + keyedClientLevel.getServerLevelKey() + "].");
// This world was identified by the server directly, so we can know for sure which folder to use.
saveFolder = new File(getSaveStructureFolderPath() + File.separatorChar + keyedClientLevel.getServerLevelKey().replaceAll(":", "@@"));
saveFolder = new File(getDefaultSaveStructureFolderPath() + File.separatorChar + keyedClientLevel.getServerLevelKey().replaceAll(":", "@@"));
}
else
{
// get the default folder
saveFolder = this.getLevelFolderWithoutSimilarityMatching(newLevelWrapper);;
saveFolder = new File(getDefaultSaveStructureFolderPath());
}
// Allow API users to override the save folder
@@ -217,7 +160,7 @@ public class ClientOnlySaveStructure implements ISaveStructure
}
private static String getSaveStructureFolderPath()
private static String getDefaultSaveStructureFolderPath()
{
String path = MC_SHARED.getInstallationDirectory().getPath() + File.separatorChar
+ SERVER_DATA_FOLDER_NAME + File.separatorChar
@@ -286,6 +229,6 @@ public class ClientOnlySaveStructure implements ISaveStructure
public void close() { }
@Override
public String toString() { return "[" + this.getClass().getSimpleName() + "@" + this.folder.getName() + "]"; }
public String toString() { return "[" + this.getClass().getSimpleName() + "@(" + StringUtil.join(";", this.levelWrapperToFileMap.values()) + ")]"; }
}
@@ -25,20 +25,20 @@ import com.seibel.distanthorizons.core.world.EWorldEnvironment;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import com.seibel.distanthorizons.coreapi.util.StringUtil;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
/**
* Designed for {@link EWorldEnvironment#CLIENT_SERVER} & {@link EWorldEnvironment#SERVER_ONLY} environments.
*
* @version 2022-12-17
*/
public class LocalSaveStructure implements ISaveStructure
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private File debugPath = new File("");
private final ConcurrentHashMap<ILevelWrapper, File> levelWrapperToFileMap = new ConcurrentHashMap<>();
@@ -53,24 +53,26 @@ public class LocalSaveStructure implements ISaveStructure
@Override
public File getSaveFolder(ILevelWrapper levelWrapper)
{
IServerLevelWrapper serverLevelWrapper = (IServerLevelWrapper) levelWrapper;
this.debugPath = serverLevelWrapper.getSaveFolder();
File saveFolder = serverLevelWrapper.getSaveFolder();
// Allow API users to override the save folder
IDhApiSaveStructure saveStructureOverride = OverrideInjector.INSTANCE.get(IDhApiSaveStructure.class);
if (saveStructureOverride != null)
return this.levelWrapperToFileMap.computeIfAbsent(levelWrapper, (newLevelWrapper) ->
{
File overrideFile = saveStructureOverride.overrideFilePath(saveFolder, levelWrapper);
if (overrideFile != null)
IServerLevelWrapper serverLevelWrapper = (IServerLevelWrapper) levelWrapper;
File saveFolder = serverLevelWrapper.getMcSaveFolder();
// Allow API users to override the save folder
IDhApiSaveStructure saveStructureOverride = OverrideInjector.INSTANCE.get(IDhApiSaveStructure.class);
if (saveStructureOverride != null)
{
LOGGER.info("Save folder overridden from ["+saveFolder.getPath()+"] -> ["+overrideFile.getPath()+"].");
saveFolder = overrideFile;
File overrideFile = saveStructureOverride.overrideFilePath(saveFolder, levelWrapper);
if (overrideFile != null)
{
LOGGER.info("Save folder overridden from [" + saveFolder.getPath() + "] -> [" + overrideFile.getPath() + "].");
saveFolder = overrideFile;
}
}
}
return saveFolder;
return saveFolder;
});
}
@@ -83,6 +85,7 @@ public class LocalSaveStructure implements ISaveStructure
public void close() throws Exception { }
@Override
public String toString() { return "[" + this.getClass().getSimpleName() + "@" + this.debugPath + "]"; }
public String toString()
{ return "[" + this.getClass().getSimpleName() + "@(" + StringUtil.join(";", this.levelWrapperToFileMap.values()) + ")]"; }
}
@@ -24,7 +24,7 @@ import java.io.File;
public interface IServerLevelWrapper extends ILevelWrapper
{
File getSaveFolder();
File getMcSaveFolder();
default String getKeyedLevelDimensionName()
{
@@ -24,6 +24,8 @@ import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegist
import com.seibel.distanthorizons.api.interfaces.world.IDhApiDimensionTypeWrapper;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import java.io.File;
/**
* Stub implementation of a Level wrapper for basic unit testing.
*
@@ -59,6 +61,10 @@ public class LevelWrapperTest implements IDhApiLevelWrapper
@Override
public IDhApiCustomRenderRegister getRenderRegister() { return null; }
@Override
public File getDhSaveFolder()
{ return null; }
}