Add logging/messaging for corrupted DB files

This commit is contained in:
James Seibel
2025-12-09 07:12:33 -06:00
parent 5ca754d2ac
commit 26d4220967
26 changed files with 171 additions and 78 deletions
@@ -47,6 +47,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -80,8 +82,8 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
// constructor //
//=============//
public GeneratedFullDataSourceProvider(IDhLevel level, ISaveStructure saveStructure) { super(level, saveStructure); }
public GeneratedFullDataSourceProvider(IDhLevel level, ISaveStructure saveStructure, @Nullable File saveDirOverride)
public GeneratedFullDataSourceProvider(IDhLevel level, ISaveStructure saveStructure) throws SQLException, IOException { super(level, saveStructure); }
public GeneratedFullDataSourceProvider(IDhLevel level, ISaveStructure saveStructure, @Nullable File saveDirOverride) throws SQLException, IOException
{
super(level, saveStructure, saveDirOverride);
@@ -31,6 +31,8 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -58,7 +60,8 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide
public RemoteFullDataSourceProvider(
IDhLevel level, ISaveStructure saveStructure, @Nullable File saveDirOverride,
@Nullable SyncOnLoadRequestQueue syncOnLoadRequestQueue)
@Nullable SyncOnLoadRequestQueue syncOnLoadRequestQueue
) throws SQLException, IOException
{
super(level, saveStructure, saveDirOverride);
this.syncOnLoadRequestQueue = syncOnLoadRequestQueue;
@@ -43,7 +43,7 @@ public class FullDataSourceProviderV1<TDhLevel extends IDhLevel>
// constructor //
//=============//
public FullDataSourceProviderV1(TDhLevel level, File saveDir)
public FullDataSourceProviderV1(TDhLevel level, File saveDir) throws SQLException, IOException
{
this.level = level;
this.saveDir = saveDir;
@@ -52,7 +52,7 @@ public class FullDataSourceProviderV1<TDhLevel extends IDhLevel>
LOGGER.warn("Unable to create full data folder, file saving may fail.");
}
this.repo = this.createRepo();
this.repo = new FullDataSourceV1Repo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, new File(this.saveDir.getPath() + File.separator + ISaveStructure.DATABASE_NAME));
}
@@ -61,21 +61,6 @@ public class FullDataSourceProviderV1<TDhLevel extends IDhLevel>
// abstract methods //
//==================//
/** When this is called the parent folders should be created */
protected FullDataSourceV1Repo createRepo()
{
try
{
return new FullDataSourceV1Repo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, new File(this.saveDir.getPath() + File.separator + ISaveStructure.DATABASE_NAME));
}
catch (SQLException e)
{
// should only happen if there is an issue with the database (it's locked or can't be created if missing)
// or the database update failed
throw new RuntimeException(e);
}
}
protected FullDataSourceV1 createDataSourceFromDto(FullDataSourceV1DTO dto) throws InterruptedException, IOException, DataCorruptedException
{
FullDataSourceV1 dataSource = FullDataSourceV1.createEmpty(dto.pos);
@@ -14,6 +14,8 @@ import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
@@ -62,7 +64,8 @@ public class DataMigratorV1 implements IDebugRenderable, AutoCloseable
public DataMigratorV1(
FullDataUpdaterV2 dataUpdater,
IDhLevel level, String levelId, File saveDir)
IDhLevel level, String levelId, File saveDir
) throws SQLException, IOException
{
this.dataUpdater = dataUpdater;
this.saveDir = saveDir;
@@ -96,11 +96,11 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
// constructor //
//=============//
public FullDataSourceProviderV2(IDhLevel level, ISaveStructure saveStructure) { this(level, saveStructure, null); }
public FullDataSourceProviderV2(IDhLevel level, ISaveStructure saveStructure, @Nullable File saveDirOverride)
public FullDataSourceProviderV2(IDhLevel level, ISaveStructure saveStructure) throws SQLException, IOException { this(level, saveStructure, null); }
public FullDataSourceProviderV2(IDhLevel level, ISaveStructure saveStructure, @Nullable File saveDirOverride) throws SQLException, IOException
{
this.saveDir = (saveDirOverride == null) ? saveStructure.getSaveFolder(level.getLevelWrapper()) : saveDirOverride;
this.repo = this.createRepo();
this.repo = new FullDataSourceV2Repo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, new File(this.saveDir.getPath() + File.separator + ISaveStructure.DATABASE_NAME));
this.level = level;
this.levelId = this.level.getLevelWrapper().getDhIdentifier();
@@ -112,19 +112,6 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus);
}
private FullDataSourceV2Repo createRepo()
{
try
{
return new FullDataSourceV2Repo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, new File(this.saveDir.getPath() + File.separator + ISaveStructure.DATABASE_NAME));
}
catch (SQLException e)
{
// should only happen if there is an issue with the database (it's locked or the folder path is missing)
// or the database update failed
throw new RuntimeException(e);
}
}
@@ -239,7 +226,27 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
catch (InterruptedException ignore) { }
catch (IOException e)
{
LOGGER.warn("File read Error for pos ["+DhSectionPos.toString(pos)+"], error: "+e.getMessage(), e);
String message = e.getMessage();
if (CORRUPT_DATA_ERRORS_LOGGED.add(message))
{
LOGGER.warn("File read Error for pos [" + DhSectionPos.toString(pos) + "], this error message will only be logged once, error: [" + message + "].", e);
}
}
catch (IllegalStateException e)
{
String message = e.getMessage();
if (CORRUPT_DATA_ERRORS_LOGGED.add(message))
{
LOGGER.warn("Incorrectly formatted data for: [" + DhSectionPos.toString(pos) + "], this error message will only be logged once, error: [" + message + "].", e);
}
}
catch (Exception e)
{
String message = e.getMessage();
if (CORRUPT_DATA_ERRORS_LOGGED.add(message))
{
LOGGER.warn("Unexpected error getting: [" + DhSectionPos.toString(pos) + "], this error message will only be logged once, error: [" + message + "].", e);
}
}
// an error occurred
@@ -216,7 +216,7 @@ public class JarMain
{
repo = new FullDataSourceV2Repo(FullDataSourceV2Repo.DEFAULT_DATABASE_TYPE, dbFile);
}
catch (SQLException e)
catch (SQLException | IOException e)
{
LOGGER.error("Failed to initialize connection with database: ["+exportFile.getAbsolutePath()+"], error: ["+e.getMessage()+"].", e);
return;
@@ -55,6 +55,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -106,9 +107,9 @@ public abstract class AbstractDhLevel implements IDhLevel
{
newChunkHashRepo = new ChunkHashRepo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, databaseFile);
}
catch (SQLException e)
catch (SQLException | IOException e)
{
LOGGER.error("Unable to create [ChunkHashRepo], error: ["+e.getMessage()+"].", e);
LOGGER.fatal("Unable to create ["+ChunkHashRepo.class.getSimpleName()+"], error: ["+e.getMessage()+"].", e);
}
this.chunkHashRepo = newChunkHashRepo;
@@ -119,9 +120,9 @@ public abstract class AbstractDhLevel implements IDhLevel
{
newBeaconBeamRepo = new BeaconBeamRepo(AbstractDhRepo.DEFAULT_DATABASE_TYPE, databaseFile);
}
catch (SQLException e)
catch (SQLException | IOException e)
{
LOGGER.error("Unable to create [BeaconBeamRepo], error: ["+e.getMessage()+"].", e);
LOGGER.error("Unable to create ["+BeaconBeamRepo.class.getSimpleName()+"], error: ["+e.getMessage()+"].", e);
}
this.beaconBeamRepo = newBeaconBeamRepo;
}
@@ -29,6 +29,8 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.*;
@@ -56,16 +58,19 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
// constructor //
//=============//
public AbstractDhServerLevel(ISaveStructure saveStructure, IServerLevelWrapper serverLevelWrapper, ServerPlayerStateManager serverPlayerStateManager)
{
this(saveStructure, serverLevelWrapper, serverPlayerStateManager, true);
}
public AbstractDhServerLevel(
ISaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
ServerPlayerStateManager serverPlayerStateManager
) throws SQLException, IOException
{ this(saveStructure, serverLevelWrapper, serverPlayerStateManager, true); }
public AbstractDhServerLevel(
ISaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
ServerPlayerStateManager serverPlayerStateManager,
boolean runRepoReliantSetup
)
) throws SQLException, IOException
{
if (saveStructure.getSaveFolder(serverLevelWrapper).mkdirs())
{
@@ -49,6 +49,8 @@ import org.jetbrains.annotations.Nullable;
import javax.annotation.CheckForNull;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -94,9 +96,18 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
// constructor //
//=============//
public DhClientLevel(ISaveStructure saveStructure, IClientLevelWrapper clientLevelWrapper, @Nullable ClientNetworkState networkState)
public DhClientLevel(
ISaveStructure saveStructure,
IClientLevelWrapper clientLevelWrapper,
@Nullable ClientNetworkState networkState
) throws SQLException, IOException
{ this(saveStructure, clientLevelWrapper, null, networkState); }
public DhClientLevel(ISaveStructure saveStructure, IClientLevelWrapper clientLevelWrapper, @Nullable File fullDataSaveDirOverride, @Nullable ClientNetworkState networkState)
public DhClientLevel(
ISaveStructure saveStructure,
IClientLevelWrapper clientLevelWrapper,
@Nullable File fullDataSaveDirOverride,
@Nullable ClientNetworkState networkState
) throws SQLException, IOException
{
File saveFolder = saveStructure.getSaveFolder(clientLevelWrapper);
File pre23Folder = saveStructure.getPre23SaveFolder(clientLevelWrapper);
@@ -33,6 +33,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapp
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/** The level used for a singleplayer world */
@@ -48,7 +50,11 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli
// constructor //
//=============//
public DhClientServerLevel(ISaveStructure saveStructure, IServerLevelWrapper serverLevelWrapper, ServerPlayerStateManager serverPlayerStateManager)
public DhClientServerLevel(
ISaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
ServerPlayerStateManager serverPlayerStateManager
) throws SQLException, IOException
{
super(saveStructure, serverLevelWrapper, serverPlayerStateManager, false);
@@ -27,6 +27,8 @@ import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRend
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
public class DhServerLevel extends AbstractDhServerLevel
@@ -35,10 +37,12 @@ public class DhServerLevel extends AbstractDhServerLevel
// constructor //
//=============//
public DhServerLevel(ISaveStructure saveStructure, IServerLevelWrapper serverLevelWrapper, ServerPlayerStateManager serverPlayerStateManager)
{
super(saveStructure, serverLevelWrapper, serverPlayerStateManager);
}
public DhServerLevel(
ISaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
ServerPlayerStateManager serverPlayerStateManager
) throws SQLException, IOException
{ super(saveStructure, serverLevelWrapper, serverPlayerStateManager); }
@@ -28,6 +28,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.coreapi.DependencyInjection.WorldGeneratorInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import java.io.IOException;
import java.sql.SQLException;
public class ServerLevelModule implements AutoCloseable
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -44,7 +47,7 @@ public class ServerLevelModule implements AutoCloseable
// constructor //
//=============//
public ServerLevelModule(IDhServerLevel parentServerLevel, ISaveStructure saveStructure)
public ServerLevelModule(IDhServerLevel parentServerLevel, ISaveStructure saveStructure) throws SQLException, IOException
{
this.parentServerLevel = parentServerLevel;
this.saveStructure = saveStructure;
@@ -75,7 +75,7 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
//=============//
/** @throws SQLException if the repo is unable to access the database or has trouble updating said database. */
public AbstractDhRepo(String databaseType, File databaseFile, Class<? extends TDTO> dtoClass) throws SQLException
public AbstractDhRepo(String databaseType, File databaseFile, Class<? extends TDTO> dtoClass) throws SQLException, IOException
{
this.databaseType = databaseType;
this.databaseFile = databaseFile;
@@ -107,7 +107,7 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
{
if (!parentFolder.mkdirs())
{
throw new RuntimeException("Unable to create the necessary parent folders for the database file at location ["+databaseFile.getPath()+"].");
throw new IOException("Unable to create the necessary parent folders for the database file at location ["+databaseFile.getPath()+"].");
}
}
@@ -119,18 +119,18 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
}
catch (IOException e)
{
throw new RuntimeException("Unable to create database file at location ["+databaseFile.getPath()+"] due to error: ["+e.getMessage()+"]", e);
throw new IOException("Unable to create database file at location ["+databaseFile.getPath()+"] due to error: ["+e.getMessage()+"]", e);
}
}
}
if (!databaseFile.canRead())
{
throw new RuntimeException("Unable to read database file at location ["+databaseFile.getPath()+"], please make sure the folder and file has the correct permissions.");
throw new IOException("Unable to read database file at location ["+databaseFile.getPath()+"], please make sure the folder and file has the correct permissions.");
}
if (!databaseFile.canWrite())
{
throw new RuntimeException("Unable to write database file at location ["+databaseFile.getPath()+"], please make sure the folder and file aren't set to read-only.");
throw new IOException("Unable to write database file at location ["+databaseFile.getPath()+"], please make sure the folder and file aren't set to read-only.");
}
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -47,7 +48,7 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
// constructor //
//=============//
public BeaconBeamRepo(String databaseType, File databaseFile) throws SQLException
public BeaconBeamRepo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, BeaconBeamDTO.class);
}
@@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -40,7 +41,7 @@ public class ChunkHashRepo extends AbstractDhRepo<DhChunkPos, ChunkHashDTO>
// constructor //
//=============//
public ChunkHashRepo(String databaseType, File databaseFile) throws SQLException
public ChunkHashRepo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, ChunkHashDTO.class);
}
@@ -28,6 +28,7 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -45,7 +46,7 @@ public class FullDataSourceV1Repo extends AbstractDhRepo<Long, FullDataSourceV1D
// constructor //
//=============//
public FullDataSourceV1Repo(String databaseType, File databaseFile) throws SQLException
public FullDataSourceV1Repo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, FullDataSourceV1DTO.class);
}
@@ -51,7 +51,7 @@ public class FullDataSourceV2Repo extends AbstractDhRepo<Long, FullDataSourceV2D
// constructor //
//=============//
public FullDataSourceV2Repo(String databaseType, File databaseFile) throws SQLException
public FullDataSourceV2Repo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, FullDataSourceV2DTO.class);
}
@@ -54,7 +54,13 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
public void addPlayer(IServerPlayerWrapper serverPlayer)
{
ServerPlayerState playerState = this.serverPlayerStateManager.registerJoinedPlayer(serverPlayer);
((TDhServerLevel) this.getOrLoadServerLevel(serverPlayer.getLevel())).addPlayer(serverPlayer);
AbstractDhServerLevel serverLevel = (AbstractDhServerLevel) this.getOrLoadServerLevel(serverPlayer.getLevel());
if (serverLevel == null)
{
return;
}
serverLevel.addPlayer(serverPlayer);
Iterator<TDhServerLevel> it = this.dhLevelByLevelWrapper.values().stream().distinct().iterator();
while (it.hasNext())
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.world;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.level.DhClientServerLevel;
import com.seibel.distanthorizons.core.util.ThreadUtil;
import com.seibel.distanthorizons.core.util.objects.EventLoop;
@@ -67,9 +68,22 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
{
return this.dhLevelByLevelWrapper.computeIfAbsent(wrapper, (levelWrapper) ->
{
DhClientServerLevel level = new DhClientServerLevel(this.saveStructure, (IServerLevelWrapper) levelWrapper, this.getServerPlayerStateManager());
this.dhLevels.add(level);
return level;
try
{
DhClientServerLevel level = new DhClientServerLevel(this.saveStructure, (IServerLevelWrapper) levelWrapper, this.getServerPlayerStateManager());
this.dhLevels.add(level);
return level;
}
catch (Exception e)
{
LOGGER.fatal("Failed to load client-server level, error: ["+e.getMessage()+"].", e);
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
"\u00A7c" + "Distant Horizons: ClientServer level loading failed." + "\u00A7r \n" +
"Unable to load level ["+levelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
return null;
}
});
}
else
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.world;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
import com.seibel.distanthorizons.core.level.DhClientLevel;
import com.seibel.distanthorizons.core.level.IDhLevel;
@@ -75,7 +76,23 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld
}
return this.levels.computeIfAbsent((IClientLevelWrapper) wrapper,
(clientLevelWrapper) -> new DhClientLevel(this.saveStructure, clientLevelWrapper, this.networkState));
(clientLevelWrapper) ->
{
try
{
return new DhClientLevel(this.saveStructure, clientLevelWrapper, this.networkState);
}
catch (Exception e)
{
LOGGER.fatal("Failed to load client level, error: ["+e.getMessage()+"].", e);
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
"\u00A7c" + "Distant Horizons: Client level loading failed." + "\u00A7r \n" +
"Unable to load level ["+clientLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
return null;
}
});
}
@Override
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.world;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.level.DhServerLevel;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
@@ -51,7 +52,23 @@ public class DhServerWorld extends AbstractDhServerWorld<DhServerLevel>
}
return this.dhLevelByLevelWrapper.computeIfAbsent(wrapper,
(serverLevelWrapper) -> new DhServerLevel(this.saveStructure, (IServerLevelWrapper) serverLevelWrapper, this.getServerPlayerStateManager()));
(serverLevelWrapper) ->
{
try
{
return new DhServerLevel(this.saveStructure, (IServerLevelWrapper) serverLevelWrapper, this.getServerPlayerStateManager());
}
catch (Exception e)
{
LOGGER.fatal("Failed to load server level, error: ["+e.getMessage()+"].", e);
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
"\u00A7c" + "Distant Horizons: Server level loading failed." + "\u00A7r \n" +
"Unable to load level ["+serverLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
return null;
}
});
}
@Override
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManag
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.jetbrains.annotations.Nullable;
/** Used both for dedicated server and singleplayer worlds */
public interface IDhServerWorld extends IDhWorld
@@ -33,6 +34,7 @@ public interface IDhServerWorld extends IDhWorld
void removePlayer(IServerPlayerWrapper serverPlayer);
void changePlayerLevel(IServerPlayerWrapper player, IServerLevelWrapper originLevel, IServerLevelWrapper destinationLevel);
@Nullable
default IDhServerLevel getOrLoadServerLevel(ILevelWrapper levelWrapper) { return (IDhServerLevel) this.getOrLoadLevel(levelWrapper); }
}
@@ -31,6 +31,7 @@ import java.util.concurrent.CompletableFuture;
public interface IDhWorld extends Closeable
{
@Nullable
IDhLevel getOrLoadLevel(@NotNull ILevelWrapper levelWrapper);
@Nullable
IDhLevel getLevel(@NotNull ILevelWrapper wrapper);
@@ -25,6 +25,7 @@ import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -33,7 +34,7 @@ import java.util.Map;
public class TestCompoundKeyRepo extends AbstractDhRepo<DhChunkPos, TestCompoundKeyDto>
{
public TestCompoundKeyRepo(String databaseType, File databaseFile) throws SQLException
public TestCompoundKeyRepo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, TestCompoundKeyDto.class);
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -32,7 +33,7 @@ import java.util.Map;
public class TestPrimaryKeyRepo extends AbstractDhRepo<Integer, TestSingleKeyDto>
{
public TestPrimaryKeyRepo(String databaseType, File databaseFile) throws SQLException
public TestPrimaryKeyRepo(String databaseType, File databaseFile) throws SQLException, IOException
{
super(databaseType, databaseFile, TestSingleKeyDto.class);
@@ -34,6 +34,7 @@ import testItems.sql.TestPrimaryKeyRepo;
import testItems.sql.TestSingleKeyDto;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -137,7 +138,7 @@ public class DhRepoSqliteTest
Assert.assertFalse("DTO exists failed", primaryKeyRepo.existsWithKey(insertDto.getKey()));
}
catch (SQLException e)
catch (SQLException | IOException e)
{
Assert.fail(e.getMessage());
}
@@ -200,7 +201,7 @@ public class DhRepoSqliteTest
Assert.assertFalse("DTO exists failed", compoundKeyRepo.existsWithKey(insertDto.getKey()));
}
catch (SQLException e)
catch (SQLException | IOException e)
{
Assert.fail(e.getMessage());
}
@@ -330,7 +331,7 @@ public class DhRepoSqliteTest
Assert.assertNotEquals(0, primaryKeyRepo.openClosables.size());
}
}
catch (SQLException e)
catch (SQLException | IOException e)
{
Assert.fail(e.getMessage());
}
@@ -367,7 +368,7 @@ public class DhRepoSqliteTest
long endMs = System.currentTimeMillis();
System.out.println("Bulk update took ["+(endMs - startMs)+"] ms");
}
catch (SQLException e)
catch (SQLException | IOException e)
{
Assert.fail(e.getMessage());
}