diff --git a/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiMat4f.java b/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiMat4f.java index 2c05ae708..feb7594ac 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiMat4f.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiMat4f.java @@ -88,25 +88,25 @@ public class DhApiMat4f implements IDhApiCopyable /** Expects the values of the input array to be in row major order (AKA rows then columns) */ public DhApiMat4f(float[] values) { - m00 = values[0]; - m01 = values[1]; - m02 = values[2]; - m03 = values[3]; + this.m00 = values[0]; + this.m01 = values[1]; + this.m02 = values[2]; + this.m03 = values[3]; - m10 = values[4]; - m11 = values[5]; - m12 = values[6]; - m13 = values[7]; + this.m10 = values[4]; + this.m11 = values[5]; + this.m12 = values[6]; + this.m13 = values[7]; - m20 = values[8]; - m21 = values[9]; - m22 = values[10]; - m23 = values[11]; + this.m20 = values[8]; + this.m21 = values[9]; + this.m22 = values[10]; + this.m23 = values[11]; - m30 = values[12]; - m31 = values[13]; - m32 = values[14]; - m33 = values[15]; + this.m30 = values[12]; + this.m31 = values[13]; + this.m32 = values[14]; + this.m33 = values[15]; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 8e5cde40a..739dc00da 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -25,6 +25,7 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure; +import com.seibel.distanthorizons.core.network.messages.MessageRegistry; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.renderer.FadeRenderer; @@ -355,6 +356,11 @@ public class ClientApi // networking // //============// + /** + * Forwards a decoded message into the registered handlers. + * + * @see MessageRegistry + */ public void pluginMessageReceived(@NotNull AbstractNetworkMessage message) { NetworkSession networkSession = this.pluginChannelApi.networkSession; @@ -430,7 +436,9 @@ public class ClientApi try { - if (!RenderUtil.shouldLodsRender(levelWrapper)) + // TODO write this message to the F3 menu so people can see when a different mod screws with the lightmap + String reasonLodsCannotRender = RenderUtil.shouldLodsRender(levelWrapper, renderEventParam); + if (reasonLodsCannotRender != null) { return; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java index d852c1504..e09399d51 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.api.internal; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelUnloadEvent; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; +import com.seibel.distanthorizons.core.network.messages.MessageRegistry; import com.seibel.distanthorizons.core.world.*; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; @@ -186,6 +187,11 @@ public class ServerApi } } + /** + * Forwards a decoded message into the registered handlers. + * + * @see MessageRegistry + */ public void pluginMessageReceived(IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) { if (DhApiWorldProxy.INSTANCE.worldLoaded() && DhApiWorldProxy.INSTANCE.getReadOnly()) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/listeners/ConfigChangeListener.java b/core/src/main/java/com/seibel/distanthorizons/core/config/listeners/ConfigChangeListener.java index d05fd938d..d969f8995 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/listeners/ConfigChangeListener.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/listeners/ConfigChangeListener.java @@ -54,9 +54,9 @@ public class ConfigChangeListener implements IConfigListener, Closeable public void onConfigValueSet() { T newValue = this.configEntry.get(); - if (newValue != previousValue) + if (newValue != this.previousValue) { - previousValue = newValue; + this.previousValue = newValue; this.onValueChangeFunc.accept(newValue); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/types/AbstractConfigType.java b/core/src/main/java/com/seibel/distanthorizons/core/config/types/AbstractConfigType.java index d1b903f11..0542cf647 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/types/AbstractConfigType.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/types/AbstractConfigType.java @@ -33,6 +33,7 @@ public abstract class AbstractConfigType public String category = ""; // This should only be set once in the init public String name; // This should only be set once in the init protected final T defaultValue; + protected final boolean isFloatingPointNumber; protected T value; public ConfigBase configBase; @@ -40,54 +41,45 @@ public abstract class AbstractConfigType protected EConfigEntryAppearance appearance; - protected AbstractConfigType(EConfigEntryAppearance appearance, T value) + + + //=============// + // constructor // + //=============// + + protected AbstractConfigType(EConfigEntryAppearance appearance, T defaultValue) { - this.defaultValue = value; - this.value = value; + this.defaultValue = defaultValue; + this.value = defaultValue; this.appearance = appearance; + + Class defaultValueClass = defaultValue.getClass(); + this.isFloatingPointNumber = (defaultValueClass == Double.class || defaultValueClass == Float.class); } + + //=========// + // methods // + //=========// + /** Gets the value */ - public T get() - { - return this.value; - } + public T get() { return this.value; } /** Sets the value */ - public void set(T newValue) - { - this.value = newValue; - } + public void set(T newValue) { this.value = newValue; } - public EConfigEntryAppearance getAppearance() - { - return appearance; - } - public void setAppearance(EConfigEntryAppearance newAppearance) - { - this.appearance = newAppearance; - } + public EConfigEntryAppearance getAppearance() { return this.appearance; } + public void setAppearance(EConfigEntryAppearance newAppearance) { this.appearance = newAppearance; } - public String getCategory() - { - return this.category; - } - public String getName() - { - return this.name; - } - public String getNameWCategory() - { - return (this.category.isEmpty() ? "" : this.category + ".") + this.name; - } + public String getCategory() { return this.category; } + public String getName() { return this.name; } + public String getNameWCategory() { return (this.category.isEmpty() ? "" : this.category + ".") + this.name; } - // Gets the class of T - public Class getType() - { - return this.defaultValue.getClass(); - } + /** Gets the class of T */ + public Class getType() { return this.defaultValue.getClass(); } + public boolean typeIsFloatingPointNumber() { return this.isFloatingPointNumber; } protected static abstract class Builder { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java index 47cfc5e98..cda82959a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java @@ -267,7 +267,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I // the server timestamp will be null if no LOD data exists for this position Long serverTimestamp = this.serverside.fullDataFileHandler.getTimestampForPos(message.sectionPos); if (serverTimestamp == null - || serverTimestamp <= clientTimestamp) + || serverTimestamp <= clientTimestamp) { // either no data exists to sync, or the client is already up to date rateLimiterSet.syncOnLoginRateLimiter.release(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/sql/repo/FullDataSourceV2Repo.java b/core/src/main/java/com/seibel/distanthorizons/core/sql/repo/FullDataSourceV2Repo.java index 6558775ee..9280f2ec3 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/sql/repo/FullDataSourceV2Repo.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/sql/repo/FullDataSourceV2Repo.java @@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiDataCompressionMode; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.sql.DbConnectionClosedException; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream; import it.unimi.dsi.fastutil.longs.LongArrayList; @@ -34,6 +35,7 @@ import java.io.File; import java.io.IOException; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -311,6 +313,10 @@ public class FullDataSourceV2Repo extends AbstractDhRepo> row = this.queryDictionary(preparedStatement); return !row.isEmpty() ? (Long) row.get(0).get("LastModifiedUnixDateTime") : null; } + catch (DbConnectionClosedException e) + { + return null; + } catch (SQLException e) { throw new RuntimeException(e); @@ -342,6 +348,10 @@ public class FullDataSourceV2Repo extends AbstractDhRepo (long) row.get("LastModifiedUnixDateTime")) ); } + catch (DbConnectionClosedException e) + { + return new HashMap<>(); + } catch (SQLException e) { throw new RuntimeException(e); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java index 37dc6957f..2fdbe6d1b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.util; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; @@ -164,37 +165,43 @@ public class RenderUtil return -1.0f; } - /** @return false if LODs shouldn't be rendered for any reason */ - public static boolean shouldLodsRender(ILevelWrapper levelWrapper) + /** @return a message if LODs shouldn't be rendered, null if the LODs can render */ + public static String shouldLodsRender(ILevelWrapper levelWrapper, DhApiRenderParam renderEventParam) { if (!MC.playerExists()) { - return false; + return "No Player Exists"; } if (levelWrapper == null) { - return false; + return "No Level Given"; } IDhClientWorld clientWorld = SharedApi.getIDhClientWorld(); if (clientWorld == null) { - return false; + return "No Client World Loaded"; } IDhClientLevel level = clientWorld.getClientLevel(levelWrapper); if (level == null) { - return false; //Level is not ready yet. + return "No Client Level Loaded"; //Level is not ready yet. } if (MC_RENDER.getLightmapWrapper(levelWrapper) == null) { - return false; + return "No Lightmap loaded"; } - return true; + if (renderEventParam.dhModelViewMatrix == null + || renderEventParam.mcModelViewMatrix == null) + { + return "No MVM or Proj Matrix Given"; + } + + return null; } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/ILevelWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/ILevelWrapper.java index d10b8e71b..652d7be55 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/ILevelWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/ILevelWrapper.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.world; +import com.google.common.primitives.Longs; import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper; import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; @@ -26,10 +27,12 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; +import org.apache.commons.codec.binary.Base32; /** Can be either a Server world or a Client world. */ public interface ILevelWrapper extends IDhApiLevelWrapper, IBindable { + Base32 base32 = new Base32(true); @Override IDimensionTypeWrapper getDimensionType(); @@ -38,12 +41,21 @@ public interface ILevelWrapper extends IDhApiLevelWrapper, IBindable String getDimensionName(); long getHashedSeed(); + /** + * Returns the result of {@link #getHashedSeed()}, encoded into a short string.
+ * Prefer using this method over stringifying the number directly. + */ + default String getHashedSeedEncoded() + { + String encoded = base32.encodeAsString(Longs.toByteArray(this.getHashedSeed())); + return encoded.substring(0, 13).toLowerCase(); // Remaining 3 chars are padding + } /** * A string intended to uniquely identify this level. */ - @Override - default String getDhIdentifier() { return this.getDimensionName() + "_" + this.getHashedSeed(); } + @Override + String getDhIdentifier(); @Override boolean hasCeiling(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java index c4e419d12..cfc6096c3 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java @@ -45,12 +45,12 @@ public interface IServerLevelWrapper extends ILevelWrapper .replaceAll(" ", "_"); levelKeyPrefix += (!levelKeyPrefix.isEmpty() ? "_" : "") + cleanWorldFolderName - + "_" + this.getHashedSeed(); + + "_" + this.getHashedSeedEncoded(); } if (levelKeyPrefix.isEmpty()) { - levelKeyPrefix = String.valueOf(this.getHashedSeed()); + levelKeyPrefix = this.getHashedSeedEncoded(); } String mainPart = "@" + dimensionName;