diff --git a/build.gradle b/build.gradle index 0b216fbce..62a3ca144 100644 --- a/build.gradle +++ b/build.gradle @@ -248,7 +248,7 @@ subprojects { p -> // We cannot relocate this library since we call some MC classes that reference it implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}") - forgeShadowMe("com.github.luben:zstd-jni:1.5.7-4") + forgeShadowMe("com.github.luben:zstd-jni:${rootProject.zstd_version}") // Compression forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4 diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java index 75c863235..327879721 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java @@ -1,6 +1,7 @@ package com.seibel.distanthorizons.common.wrappers.block; import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dataObjects.BlockBiomeWrapperPair; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; @@ -9,6 +10,7 @@ import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import it.unimi.dsi.fastutil.longs.LongArrayList; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; @@ -39,13 +41,13 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter private static final ConcurrentHashMap> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>(); #endif - private static final ConcurrentHashMap COLOR_BY_BIOME_WRAPPER = new ConcurrentHashMap<>(); - + private static final ConcurrentHashMap COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>(); /** returned if the color cache is incomplete */ public static final int INVALID_COLOR = Integer.MIN_VALUE; protected BiomeWrapper biomeWrapper; + protected BlockStateWrapper blockStateWrapper; protected FullDataSourceV2 fullDataSource; protected int smoothingRadiusInBlocks; protected IClientLevelWrapper clientLevelWrapper; @@ -62,9 +64,10 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter * Mutates this getter so we can access the necessary * variables for tint getting. */ - public void update(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) + public void update(BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) { this.biomeWrapper = biomeWrapper; + this.blockStateWrapper = blockStateWrapper; this.fullDataSource = fullDataSource; this.clientLevelWrapper = clientLevelWrapper; this.smoothingRadiusInBlocks = Config.Client.Advanced.Graphics.Quality.lodBiomeBlending.get(); @@ -184,9 +187,11 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter */ private int tryGetClientBiomeColor(@Nullable ColorResolver colorResolver, BiomeWrapper biomeWrapper) { + BlockBiomeWrapperPair pair = BlockBiomeWrapperPair.get(this.blockStateWrapper, biomeWrapper); + // use the cached color if possible - int cachedColor = COLOR_BY_BIOME_WRAPPER.getOrDefault(biomeWrapper, INVALID_COLOR); - if (cachedColor != INVALID_COLOR) + Integer cachedColor = COLOR_BY_BLOCK_BIOME_PAIR.get(pair); // explicit Integer return here reduces unnecessary allocations + if (cachedColor != null) { return cachedColor; } @@ -199,9 +204,10 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter return INVALID_COLOR; } - return COLOR_BY_BIOME_WRAPPER.computeIfAbsent(biomeWrapper, - // in James' testing the block position isn't needed so we can just default to (0,0) - (newBiomeWrapper) -> colorResolver.getColor(unwrapClientBiome(biomeWrapper), 0, 0)); + + int color = colorResolver.getColor(unwrapClientBiome(biomeWrapper), 0, 0); + COLOR_BY_BLOCK_BIOME_PAIR.put(pair, color); + return color; } protected static Biome unwrapClientBiome(BiomeWrapper biomeWrapper) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java index 2118b5f67..79987701b 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java @@ -94,6 +94,7 @@ public class ClientBlockStateColorCache private final IClientLevelWrapper clientLevelWrapper; private final BlockState blockState; + private final BlockStateWrapper blockStateWrapper; private boolean isColorResolved = false; private int baseColor = 0; @@ -173,10 +174,11 @@ public class ClientBlockStateColorCache // constructor // //=============// - public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel) + public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper) { this.blockState = blockState; - this.clientLevelWrapper = samplingLevel; + this.blockStateWrapper = BlockStateWrapper.fromBlockState(blockState, clientLevelWrapper); + this.clientLevelWrapper = clientLevelWrapper; this.resolveColors(); } @@ -472,7 +474,7 @@ public class ClientBlockStateColorCache try { TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get(); - tintOverride.update(biomeWrapper, fullDataSource, this.clientLevelWrapper); + tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper); // try using DH's cached tint values first if possible tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos)); @@ -503,7 +505,7 @@ public class ClientBlockStateColorCache // specifically oceans don't render correctly TintGetterOverride tintOverride = TintOverrideGetter.get(); - tintOverride.update(biomeWrapper, fullDataSource, this.clientLevelWrapper); + tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper); tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos)); if (tintColor == AbstractDhTintGetter.INVALID_COLOR) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java index 3a26bdf62..c95337978 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java @@ -51,9 +51,9 @@ public class TintGetterOverride extends AbstractDhTintGetter public TintGetterOverride() { } - public void update(LevelReader parent, BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) + public void update(LevelReader parent, BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) { - super.update(biomeWrapper, fullDataSource, clientLevelWrapper); + super.update(biomeWrapper, blockStateWrapper, fullDataSource, clientLevelWrapper); this.parent = parent; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java index e734fa846..2c80c5b06 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java @@ -199,13 +199,17 @@ public class ClientLevelWrapper implements IClientLevelWrapper //====================// @Override - public int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper) + public int getBlockColor(DhBlockPos blockPos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper) { - ClientBlockStateColorCache blockColorCache = this.blockColorCacheByBlockState.computeIfAbsent( - ((BlockStateWrapper) blockWrapper).blockState, - this.createCachedBlockColorCacheFunc); + ClientBlockStateColorCache blockColorCache = this.blockColorCacheByBlockState.get(((BlockStateWrapper) blockWrapper).blockState); + if (blockColorCache == null) + { + blockColorCache = this.blockColorCacheByBlockState.computeIfAbsent( + ((BlockStateWrapper) blockWrapper).blockState, + this.createCachedBlockColorCacheFunc); + } - return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, pos); + return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, blockPos); } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java index de0552ae3..69f5155a5 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java @@ -42,6 +42,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.Abstrac import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper; import java.io.IOException; +import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.ClosedChannelException; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; @@ -681,12 +683,25 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv actualThrowable = completionException.getCause(); } - CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable); + // interrupts mean the world generator is being shut down, no need to log that + boolean isShutdownException = + actualThrowable instanceof InterruptedException + || actualThrowable instanceof ClosedByInterruptException; + if (!isShutdownException) + { + CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable); + } + return null; }); } #endif } + catch (ClosedByInterruptException ignore) + { + // this just means the world generator is being shut down + return CompletableFuture.completedFuture(null); + } catch (Exception e) { CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk [" + chunkPos + "]. Error: [" + e.getMessage() + "].", e); @@ -1124,9 +1139,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv { regionStorage.close(); } + catch (ClosedChannelException ignore) { /* world generator is being shut down */ } catch (IOException e) { - EVENT_LOGGER.error("Failed to close region file storage cache!", e); + EVENT_LOGGER.error("Failed to close region file storage cache, error: ["+e.getMessage()+"].", e); } } diff --git a/coreSubProjects b/coreSubProjects index 6bfcf3668..eea5198fb 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 6bfcf36687734894c04ee93ca4ba17bb2b6caffe +Subproject commit eea5198fb6cda0196ea714254f2515a40e72fc33 diff --git a/gradle.properties b/gradle.properties index a92a7930e..b6c6fb489 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,6 +23,7 @@ manifold_version=2025.1.27 nightconfig_version=3.6.6 lz4_version=1.8.0 xz_version=1.9 +zstd_version=1.5.7-6 # Before updating, read relocate_natives/README.md sqlite_jdbc_version=3.47.2.0 # 8.2.1 is the newest version we can use since that's the version MC 1.16.5 uses