Update core

This commit is contained in:
s809
2023-08-26 21:34:46 +05:00
parent 22680baad7
commit e9a13dffb8
20 changed files with 673 additions and 498 deletions
+3 -3
View File
@@ -33,9 +33,9 @@ build:
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1"]
script:
# this both runs the unit tests and assembles the code
- ./gradlew clean -PmcVer="${MC_VER}" --gradle-user-home cache/;
- ./gradlew build -PmcVer="${MC_VER}" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="${MC_VER}" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="${MC_VER}" -PgitMainBranch="${CI_COMMIT_BRANCH}" -PgitMainCommit="${CI_COMMIT_SHA}" -PgitCoreCommit="Unavailable (built by Gitlab CI)" --gradle-user-home cache/;
- ./gradlew build -PmcVer="${MC_VER}" -PgitMainBranch="${CI_COMMIT_BRANCH}" -PgitMainCommit="${CI_COMMIT_SHA}" -PgitCoreCommit="Unavailable (built by Gitlab CI)" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PgitMainBranch="${CI_COMMIT_BRANCH}" -PgitMainCommit="${CI_COMMIT_SHA}" -PgitCoreCommit="Unavailable (built by Gitlab CI)" --gradle-user-home cache/;
artifacts:
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
paths:
+5 -5
View File
@@ -20,7 +20,7 @@ If you want to see a quick demo, check out a video covering the mod here:
### This branch supports the following versions of Minecraft:
#### 1.20.1, 1.20
#### 1.20.1, 1.20 (Default)
Fabric: 0.14.21\
Fabric API: 0.85.0+1.20.1\
Forge: 45.1.0\
@@ -41,21 +41,21 @@ Forge: 43.2.14\
Parchment: 1.19.2:2022.11.27\
Modmenu: 4.2.0-beta.2
#### 1.18.2 (Default)
#### 1.18.2
Fabric: 0.14.21\
Fabric API: 0.76.0+1.18.2\
Forge: 40.2.10\
Parchment: 1.18.2:2022.11.06\
Modmenu: 3.2.5
#### 1.17.1, 1.17 (BROKE)
#### 1.17.1, 1.17
Fabric: 0.14.21\
Fabric API: 0.46.1+1.17\
Forge: 37.1.1\
Parchment: 1.17.1:2021.12.12\
Modmenu: 2.0.14
#### 1.16.5, 1.16.4 (BROKE)
#### 1.16.5, 1.16.4
Fabric: 0.14.21\
Fabric API: 0.42.0+1.16\
Forge: 36.2.39\
@@ -196,5 +196,5 @@ https://github.com/TheElectronWill/night-config
SVG Salamander for SVG support\
https://github.com/blackears/svgSalamander
FlatLaf for theming (for development testing, may remove later)\
FlatLaf for Java Swing theming (for development testing, may remove later, and not included in compiled jars)\
https://www.formdev.com/flatlaf/
+16 -4
View File
@@ -363,11 +363,23 @@ subprojects { p ->
def git_main_commit = "Git_not_found"
def git_core_commit = "Git_not_found"
def git_main_branch = "Git_not_found"
// These "hasProperty"'s are so that they can be passed through the cli (ie in the CI)
try {
"git rev-parse --is-inside-work-tree".execute() // If git doesnt exist, or this isnt cloned from git, then this wont work
git_main_commit = 'git rev-parse --verify HEAD'.execute().text.trim()
git_core_commit = 'git ls-tree --object-only HEAD ../coreSubProjects'.execute().text.trim() // TODO: is there a way to do this universally
git_main_branch = 'git symbolic-ref --short HEAD'.execute().text.trim()
// "git rev-parse --is-inside-work-tree".execute() // If git doesnt exist, or this isnt cloned from git, then this wont work
if (gitMainCommit != "null")
git_main_commit = gitMainCommit
else
git_main_commit = 'git rev-parse --verify HEAD'.execute().text.trim()
if (gitCoreCommit != "null")
git_core_commit = gitCoreCommit
else
git_core_commit = 'git ls-tree --object-only HEAD ../coreSubProjects'.execute().text.trim() // TODO: is there a way to do this universally
if (gitMainBranch != "null")
git_main_branch = gitMainBranch
else
git_main_branch = 'git symbolic-ref --short HEAD'.execute().text.trim()
} catch (Exception e) {
println "Git or Git project not found"
}
@@ -23,6 +23,8 @@ import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiW
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.level.IDhServerLevel;
@@ -32,11 +34,14 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.chunk.ChunkAccess;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
/**
* This handles creating abstract wrapper objects.
@@ -74,7 +79,7 @@ public class WrapperFactory implements IWrapperFactory
public IBlockStateWrapper getAirBlockStateWrapper() { return BlockStateWrapper.AIR; }
@Override
public HashMap<String, ? extends IBlockStateWrapper> getRendererIgnoredBlocks() { return BlockStateWrapper.RENDERER_IGNORED_BLOCKS; }
public HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredBlocks(levelWrapper); }
/**
@@ -114,15 +119,34 @@ public class WrapperFactory implements IWrapperFactory
}
ChunkAccess chunk = (ChunkAccess) objectArray[0];
// light source
if (!(objectArray[1] instanceof LevelReader))
// level / light source
if (!(objectArray[1] instanceof Level))
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
LevelReader lightSource = (LevelReader) objectArray[1];
// the level is needed for the DH level wrapper...
Level level = (Level) objectArray[1];
// ...the LevelReader is needed for chunk lighting
LevelReader lightSource = level;
return new ChunkWrapper(chunk, lightSource, /*A DH wrapped level isn't necessary*/null);
// level wrapper
ILevelWrapper levelWrapper;
if (level instanceof ServerLevel)
{
levelWrapper = ServerLevelWrapper.getWrapper((ServerLevel)level);
}
else if (level instanceof ClientLevel)
{
levelWrapper = ClientLevelWrapper.getWrapper((ClientLevel)level);
}
else
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
return new ChunkWrapper(chunk, lightSource, levelWrapper);
}
// incorrect number of parameters from the API
else
@@ -153,7 +177,7 @@ public class WrapperFactory implements IWrapperFactory
// MC 1.16, 1.18, 1.19, 1.20
#if POST_MC_1_17_1 || MC_1_16_5
message.append("[" + ChunkAccess.class.getName() + "], \n");
message.append("[" + LevelReader.class.getName() + "]. \n");
message.append("[" + ServerLevel.class.getName() + "] or [" + ClientLevel.class.getName() + "]. \n");
#else
// See preprocessor comment in createChunkWrapper() for full documentation
not implemented for this version of Minecraft!
@@ -19,40 +19,44 @@
package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.world.level.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import net.minecraft.client.Minecraft;
#if POST_MC_1_17
import net.minecraft.core.Holder;
import net.minecraft.resources.RegistryOps;
#endif
#if POST_MC_1_19_2
#endif
#if MC_1_16_5 || MC_1_17_1
import net.minecraft.core.Registry;
#elif MC_1_18_2 || MC_1_19_2
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.BuiltinRegistries;
#else
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
#endif
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome;
#if !PRE_MC_1_18_2
import net.minecraft.world.level.biome.Biomes;
#endif
@@ -60,135 +64,208 @@ import net.minecraft.core.registries.Registries;
public class BiomeWrapper implements IBiomeWrapper
{
private static final Logger LOGGER = LogManager.getLogger();
#if PRE_MC_1_18_2
public static final ConcurrentMap<Biome, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
public final Biome biome;
#else
public static final ConcurrentMap<Holder<Biome>, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
#endif
public static final String EMPTY_STRING = "EMPTY";
public static final BiomeWrapper EMPTY_WRAPPER = new BiomeWrapper(null, null);
// properties //
#if PRE_MC_1_18_2
public final Biome biome;
#else
public final Holder<Biome> biome;
#endif
private final ILevelWrapper levelWrapper;
/**
* Cached so it can be quickly used as a semi-stable hashing method. <br>
* This may also fix the issue where we can serialize and save after a level has been shut down.
*/
private String serializationResult = null;
/** technically final, but since it requires a method call to generate it can't be marked as such */
private String serialString = null;
//==============//
// constructors //
//==============//
static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper) {
Objects.requireNonNull(#if PRE_MC_1_18_2 biome #else biome.value() #endif);
return biomeWrapperMap.computeIfAbsent(biome, biomeHolder -> new BiomeWrapper(biomeHolder, levelWrapper));
static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
{
if (biome == null)
{
return EMPTY_WRAPPER;
}
return biomeWrapperMap.computeIfAbsent(biome, newBiome -> new BiomeWrapper(newBiome, levelWrapper));
}
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper) {
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
{
this.biome = biome;
this.levelWrapper = levelWrapper;
this.serialString = this.serialize(levelWrapper);
LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
}
//=========//
// methods //
//=========//
@Override
public String getName() {
public String getName()
{
if (this == EMPTY_WRAPPER)
{
return EMPTY_STRING;
}
#if PRE_MC_1_18_2
return biome.toString();
#else
return this.biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
#endif
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
} else if (obj == null || this.getClass() != obj.getClass()) {
}
else if (obj == null || this.getClass() != obj.getClass())
{
return false;
}
BiomeWrapper that = (BiomeWrapper) obj;
// the serialized value is used so we can test the contents instead of the references
return Objects.equals(this.serialize(), that.serialize());
return Objects.equals(this.getSerialString(), that.getSerialString());
}
@Override
public int hashCode() {
return Objects.hash(this.serialize());
}
public int hashCode() { return Objects.hash(this.getSerialString()); }
@Override
public String serialize()
public String getSerialString() { return this.serialString; }
@Override
public Object getWrappedMcObject() { return this.biome; }
@Override
public String toString() { return this.getSerialString(); }
//=======================//
// serialization methods //
//=======================//
public String serialize(ILevelWrapper levelWrapper)
{
// the result can be quickly used as a semi-stable hashing method, so it's going to be cached
if (this.serializationResult != null)
return this.serializationResult;
if (levelWrapper == null)
{
return EMPTY_STRING;
}
RegistryAccess registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess();
ResourceLocation resourceLocation;
#if MC_1_16_5 || MC_1_17_1
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
#elif MC_1_18_2 || MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
#else
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
#endif
Objects.requireNonNull(resourceLocation);
if (this.serialString == null)
{
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
ResourceLocation resourceLocation;
#if MC_1_16_5 || MC_1_17_1
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
#elif MC_1_18_2 || MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
#else
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
#endif
if (resourceLocation == null)
{
String biomeName;
#if MC_1_16_5 || MC_1_17_1
biomeName = this.biome.toString();
#else
biomeName = this.biome.value().toString();
#endif
LOGGER.warn("unable to serialize: " + biomeName);
// shouldn't normally happen, but just in case
this.serialString = "";
}
else
{
this.serialString = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
}
}
this.serializationResult = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
return this.serializationResult;
return this.serialString;
}
@Override
public ILevelWrapper getLevelWrapper() {
return levelWrapper;
}
public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException {
public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException
{
if (resourceLocationString.equals(EMPTY_STRING))
{
LOGGER.warn("["+EMPTY_STRING+"] biome string deserialized. This may mean there was a file saving error or a biome saving error.");
return EMPTY_WRAPPER;
}
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals(""))
{
LOGGER.warn("Null biome string deserialized.");
return EMPTY_WRAPPER;
}
// parse the resource location
int separatorIndex = resourceLocationString.indexOf(":");
if (separatorIndex == -1) {
if (separatorIndex == -1)
{
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
}
ResourceLocation resourceLocation = new ResourceLocation(
resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
try {
net.minecraft.core.RegistryAccess registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess();
ResourceLocation resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
try
{
Level level = (Level)levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
boolean success;
#if MC_1_16_5 || MC_1_17_1
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
success = (biome != null);
#elif MC_1_18_2 || MC_1_19_2
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
success = (unwrappedBiome != null);
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
#else
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
assert unwrappedBiome != null;
success = (unwrappedBiome != null);
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
#endif
if (!success)
{
LOGGER.warn("Unable to deserialize biome from string: [" + resourceLocationString + "]");
return EMPTY_WRAPPER;
}
return getBiomeWrapper(biome, levelWrapper);
} catch (Exception e) {
throw new IOException(
"Failed to deserialize the string [" + resourceLocationString + "] into a BiomeWrapper: " + e.getMessage(), e);
}
catch (Exception e)
{
throw new IOException("Failed to deserialize the string [" + resourceLocationString + "] into a BiomeWrapper: " + e.getMessage(), e);
}
}
@Override
public Object getWrappedMcObject() {
return this.biome;
}
@Override
public String toString() {
return this.serialize();
}
}
@@ -4,10 +4,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.apache.logging.log4j.Logger;
@@ -18,22 +15,24 @@ import java.util.concurrent.ConcurrentHashMap;
#if MC_1_16_5 || MC_1_17_1
import net.minecraft.core.Registry;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.EmptyBlockGetter;
#elif MC_1_18_2 || MC_1_19_2
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
#else
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.EmptyBlockGetter;
import org.jetbrains.annotations.NotNull;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
#endif
public class BlockStateWrapper implements IBlockStateWrapper
{
/** example "minecraft:plains" */
/** example "minecraft:water" */
public static final String RESOURCE_LOCATION_SEPARATOR = ":";
/** example "minecraft:water_STATE_{level:0}" */
public static final String STATE_STRING_SEPARATOR = "_STATE_";
@@ -42,111 +41,102 @@ public class BlockStateWrapper implements IBlockStateWrapper
// must be defined before AIR, otherwise a null pointer will be thrown
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> cache = new ConcurrentHashMap<>();
public static final BlockStateWrapper AIR = fromBlockState(BuiltInRegistries.BLOCK.get(ResourceLocation.tryParse("minecraft:air")).defaultBlockState(), null, false);
public static final String[] RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS = {"minecraft:air", "minecraft:barrier", "minecraft:structure_void", "minecraft:light"};
public static final HashMap<BlockState, String> RENDERER_IGNORED_BLOCKS_INTERNAL = getRendererIgnoredBlocksInternal(RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS);
public static final HashMap<String, ? extends IBlockStateWrapper> RENDERER_IGNORED_BLOCKS = getRendererIgnoredBlocks(RENDERER_IGNORED_BLOCKS_INTERNAL);
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
public static final String AIR_STRING = "AIR";
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
public static final String[] RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS = { AIR_STRING, "minecraft:barrier", "minecraft:structure_void", "minecraft:light" };
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
// properties //
public final BlockState blockState;
/** technically final, but since it requires a method call to generate it can't be marked as such */
private String serialString;
/**
* Cached so it can be quickly used as a semi-stable hashing method. <br>
* This may also fix the issue where we can serialize and save after a level has been shut down.
*/
private String serializationResult = null;
//==============//
// constructors //
//==============//
public static BlockStateWrapper fromBlockState(BlockState blockState, @NotNull ILevelWrapper levelWrapper)
public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper)
{
return fromBlockState(blockState, levelWrapper, true);
}
private static BlockStateWrapper fromBlockState(BlockState blockState, @Nullable ILevelWrapper levelWrapper, boolean nullCheck)
{
if (Objects.requireNonNull(blockState).isAir() && AIR != null)
if (blockState == null || blockState.isAir())
{
return AIR;
return cache.computeIfAbsent(blockState, blockState1 -> new BlockStateWrapper(blockState1, levelWrapper, nullCheck));
}
/**
* Only meant for use in the {@code RENDERER_IGNORED_BLOCKS_INTERNAL} list. Do not use elsewhere, since the {@code levelWrapper} parameter of each {@code IBlockStateWrapper} will be {@code null}, causing issues.
* @param resourceLocations The resource location(s) of the block(s) that should be ignored by the renderer, may only contain {@code [a-z0-9/._-)} characters.
* @return The default blockstate(s) of the block(s), paired with the serialized resource location(s) of the block(s), which should be passed into the {@code RENDERER_IGNORED_BLOCKS_INTERNAL} map and the {@code getRendererIgnoredBlocks} method.
*/
@SuppressWarnings("SameParameterValue")
private static @NotNull HashMap<BlockState, String> getRendererIgnoredBlocksInternal(String @NotNull ... resourceLocations)
{
HashMap<BlockState, String> blockStates = new HashMap<>();
for (String resourceLocation : resourceLocations)
{
ResourceLocation fetchedResourceLocation = Objects.requireNonNull(ResourceLocation.tryParse(resourceLocation), String.format("Supplied a resource location that couldn't be parsed by Minecraft: %s", resourceLocation));
var splitResourceLocation = resourceLocation.split(":");
if (splitResourceLocation.length == 0) {
LOGGER.warn("A resource location that should be ignored by the renderer was in an invalid format: {}", resourceLocation);
continue;
}
blockStates.put(BuiltInRegistries.BLOCK.get(fetchedResourceLocation).defaultBlockState(), splitResourceLocation[1].toUpperCase(Locale.ROOT));
}
return blockStates;
return WRAPPER_BY_BLOCK_STATE.computeIfAbsent(blockState, newBlockState -> new BlockStateWrapper(newBlockState, levelWrapper));
}
/**
* Only meant for use in the {@code RENDERER_IGNORED_BLOCKS} list. Do not use elsewhere, since the {@code levelWrapper} parameter of each {@code IBlockStateWrapper} will be {@code null}, causing issues.
* @param rendererIgnoredBlocks A map containing the blockstate(s) of the block(s), paired with the resource location(s) of the block(s) that should be ignored by the renderer.
* @return The blockstate wrapper(s) of the blockstate(s), which should be passed into the {@code RENDERER_IGNORED_BLOCKS} list.
*/
@SuppressWarnings("SameParameterValue")
private static @NotNull HashMap<String, ? extends IBlockStateWrapper> getRendererIgnoredBlocks(@NotNull Map<BlockState, String> rendererIgnoredBlocks)
private BlockStateWrapper(BlockState blockState, ILevelWrapper levelWrapper)
{
HashMap<String, BlockStateWrapper> blockStateWrappers = new HashMap<>();
for (Map.Entry<BlockState, String> blockStateResourceLocations : rendererIgnoredBlocks.entrySet())
{
blockStateWrappers.put(blockStateResourceLocations.getValue(), fromBlockState(blockStateResourceLocations.getKey(), null, false));
}
return blockStateWrappers;
}
public final BlockState blockState;
@CheckForNull
public final ILevelWrapper levelWrapper;
BlockStateWrapper(BlockState blockState, @Nullable ILevelWrapper levelWrapper)
{
this(blockState, levelWrapper, true);
}
private BlockStateWrapper(BlockState blockState, @Nullable ILevelWrapper levelWrapper, boolean nullCheck) {
this.blockState = blockState;
if (nullCheck)
{
this.levelWrapper = RENDERER_IGNORED_BLOCKS_INTERNAL.containsKey(blockState)
? null
: Objects.requireNonNull(levelWrapper);
}
else
{
this.levelWrapper = levelWrapper;
}
LOGGER.trace("Created BlockStateWrapper for [{}]", blockState);
this.serialString = this.serialize(levelWrapper);
LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"]");
}
//=========//
// methods //
//=========//
//================//
// helper methods //
//================//
/**
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
* This way the method won't accidentally be called before the deserialization can be completed.
*/
public static HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper)
{
// use the cached version if possible
if (rendererIgnoredBlocks != null)
{
return rendererIgnoredBlocks;
}
// deserialize each of the given resource locations
HashSet<IBlockStateWrapper> blockStateWrappers = new HashSet<>();
for (String blockResourceLocation : RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS)
{
try
{
BlockStateWrapper DefaultBlockStateToIgnore = (BlockStateWrapper) deserialize(blockResourceLocation, levelWrapper);
blockStateWrappers.add(DefaultBlockStateToIgnore);
if (DefaultBlockStateToIgnore == AIR)
{
continue;
}
// add all possible blockstates (to account for light blocks with different light values and such)
List<BlockState> blockStatesToIgnore = DefaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
for (BlockState blockState : blockStatesToIgnore)
{
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper);
blockStateWrappers.add(newBlockToIgnore);
}
}
catch (IOException e)
{
LOGGER.warn("Unable to deserialize rendererIgnoredBlock with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
}
}
rendererIgnoredBlocks = blockStateWrappers;
return rendererIgnoredBlocks;
}
//=================//
// wrapper methods //
//=================//
@Override
public int getOpacity()
@@ -168,134 +158,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
@Override
public String serialize()
{
// the result can be quickly used as a semi-stable hashing method, so it's going to be cached
if (this.serializationResult != null)
return this.serializationResult;
if (RENDERER_IGNORED_BLOCKS_INTERNAL.containsKey(this.blockState))
return this.serializationResult = RENDERER_IGNORED_BLOCKS_INTERNAL.get(this.blockState);
Objects.requireNonNull(levelWrapper);
RegistryAccess registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess();
ResourceLocation resourceLocation;
#if MC_1_16_5 || MC_1_17_1
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
#elif MC_1_18_2 || MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
#else
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
#endif
Objects.requireNonNull(resourceLocation);
this.serializationResult = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath()
+ STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState);
return this.serializationResult;
}
@Override
@Nullable
public ILevelWrapper getLevelWrapper() {
return levelWrapper;
}
public static IBlockStateWrapper deserialize(String resourceStateString, ILevelWrapper levelWrapper) throws IOException
{
if (resourceStateString.isEmpty())
throw new IOException("resourceStateString is empty");
if (RENDERER_IGNORED_BLOCKS_INTERNAL.containsValue(resourceStateString))
return RENDERER_IGNORED_BLOCKS.get(resourceStateString);
// Parse the BlockState
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
if (stateSeparatorIndex == -1)
{
throw new IOException("Unable to parse BlockState out of string: [" + resourceStateString + "].");
}
String blockStatePropertiesString = resourceStateString.substring(stateSeparatorIndex + STATE_STRING_SEPARATOR.length());
resourceStateString = resourceStateString.substring(0, stateSeparatorIndex);
// parse the resource location
int resourceSeparatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
if (resourceSeparatorIndex == -1)
{
throw new IOException("Unable to parse Resource Location out of string: [" + resourceStateString + "].");
}
ResourceLocation resourceLocation = new ResourceLocation(resourceStateString.substring(0, resourceSeparatorIndex), resourceStateString.substring(resourceSeparatorIndex + 1));
// attempt to get the BlockState from all possible BlockStates
try
{
Block block;
#if MC_1_16_5 || MC_1_17_1
block = Registry.BLOCK.get(resourceLocation);
#elif MC_1_18_2 || MC_1_19_2
net.minecraft.core.RegistryAccess registryAccess = ((Level)levelWrapper.getWrappedMcObject()).registryAccess();
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
#else
net.minecraft.core.RegistryAccess registryAccess = ((Level)levelWrapper.getWrappedMcObject()).registryAccess();
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
#endif
BlockState foundState = null;
List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates();
for (BlockState possibleState : possibleStateList)
{
String possibleStatePropertiesString = serializeBlockStateProperties(possibleState);
if (possibleStatePropertiesString.equals(blockStatePropertiesString))
{
foundState = possibleState;
break;
}
}
Objects.requireNonNull(foundState);
return new BlockStateWrapper(foundState, levelWrapper);
}
catch (Exception e)
{
throw new IOException("Failed to deserialize the string [" + resourceStateString + "] into a BlockStateWrapper: " + e.getMessage(), e);
}
}
/** used to compare and save BlockStates based on their properties */
private static String serializeBlockStateProperties(BlockState blockState)
{
// get the property list for this block (doesn't contain this block state's values, just the names and possible values)
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties();
// alphabetically sort the list, so they are always in the same order
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName()));
StringBuilder stringBuilder = new StringBuilder();
for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList)
{
String propertyName = property.getName();
String value = "NULL";
if (blockState.hasProperty(property))
{
value = blockState.getValue(property).toString();
}
stringBuilder.append("{");
stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value);
stringBuilder.append("}");
}
return stringBuilder.toString();
}
public String getSerialString() { return this.serialString; }
@Override
public boolean equals(Object obj)
@@ -310,16 +173,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
return false;
}
BlockStateWrapper that = (BlockStateWrapper) obj;
// the serialized value is used, so we can test the contents instead of the references
return Objects.equals(this.serialize(), that.serialize());
}
@Override
public int hashCode() {
return Objects.hash(this.serialize());
BlockStateWrapper that = (BlockStateWrapper) obj;
// the serialized value is used so we can test the contents instead of the references
return Objects.equals(this.getSerialString(), that.getSerialString());
}
@Override
public int hashCode() { return Objects.hash(this.getSerialString()); }
@Override
public Object getWrappedMcObject() { return this.blockState; }
@@ -353,8 +215,178 @@ public class BlockStateWrapper implements IBlockStateWrapper
}
@Override
public String toString() {
return this.serialize();
public String toString() { return this.getSerialString(); }
//=======================//
// serialization methods //
//=======================//
private String serialize(ILevelWrapper levelWrapper)
{
if (this.blockState == null)
{
return AIR_STRING;
}
// older versions of MC have a static registry
#if !(MC_1_16_5 || MC_1_17_1)
Level level = (Level)levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
#endif
ResourceLocation resourceLocation;
#if MC_1_16_5 || MC_1_17_1
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
#elif MC_1_18_2 || MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
#else
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
#endif
if (resourceLocation == null)
{
LOGGER.warn("No ResourceLocation found, unable to serialize: " + this.blockState);
return AIR_STRING;
}
this.serialString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath()
+ STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState);
return this.serialString;
}
/** will only work if a level is currently loaded */
public static IBlockStateWrapper deserialize(String resourceStateString, ILevelWrapper levelWrapper) throws IOException
{
if (resourceStateString.equals(AIR_STRING) || resourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case
{
return AIR;
}
// try to parse out the BlockState
String blockStatePropertiesString = null; // will be null if no properties were included
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
if (stateSeparatorIndex != -1)
{
// blockstate properties found
blockStatePropertiesString = resourceStateString.substring(stateSeparatorIndex + STATE_STRING_SEPARATOR.length());
resourceStateString = resourceStateString.substring(0, stateSeparatorIndex);
}
// parse the resource location
int resourceSeparatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
if (resourceSeparatorIndex == -1)
{
throw new IOException("Unable to parse Resource Location out of string: [" + resourceStateString + "].");
}
ResourceLocation resourceLocation = new ResourceLocation(resourceStateString.substring(0, resourceSeparatorIndex), resourceStateString.substring(resourceSeparatorIndex + 1));
// attempt to get the BlockState from all possible BlockStates
try
{
#if !(MC_1_16_5 || MC_1_17_1)
// use the given level if possible, otherwise try using the currently loaded one
Level level = (levelWrapper != null ? (Level)levelWrapper.getWrappedMcObject() : null);
level = (level == null ? Minecraft.getInstance().level : level);
#endif
Block block;
#if MC_1_16_5 || MC_1_17_1
block = Registry.BLOCK.get(resourceLocation);
#elif MC_1_18_2 || MC_1_19_2
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
#else
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
#endif
if (block == null)
{
// shouldn't normally happen, but here to make the compiler happy
LOGGER.warn("Unable to find BlockState with the resourceLocation [" + resourceLocation + "] and properties: [" + blockStatePropertiesString + "]. Air will be used instead, some data may be lost.");
return AIR;
}
// attempt to find the blockstate from all possibilities
BlockState foundState = null;
if (blockStatePropertiesString != null)
{
List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates();
for (BlockState possibleState : possibleStateList)
{
String possibleStatePropertiesString = serializeBlockStateProperties(possibleState);
if (possibleStatePropertiesString.equals(blockStatePropertiesString))
{
foundState = possibleState;
break;
}
}
}
// use the default if no state was found or given
if (foundState == null)
{
if (blockStatePropertiesString != null)
{
// we should have found a blockstate, but didn't
LOGGER.warn("Unable to find BlockState for Block [" + resourceLocation + "] with properties: [" + blockStatePropertiesString + "]. Using the default block state.");
}
foundState = block.defaultBlockState();
}
return new BlockStateWrapper(foundState, levelWrapper);
}
catch (Exception e)
{
throw new IOException("Failed to deserialize the string [" + resourceStateString + "] into a BlockStateWrapper: " + e.getMessage(), e);
}
}
/** used to compare and save BlockStates based on their properties */
private static String serializeBlockStateProperties(BlockState blockState)
{
// get the property list for this block (doesn't contain this block state's values, just the names and possible values)
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties();
// alphabetically sort the list so they are always in the same order
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName()));
StringBuilder stringBuilder = new StringBuilder();
for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList)
{
String propertyName = property.getName();
String value = "NULL";
if (blockState.hasProperty(property))
{
value = blockState.getValue(property).toString();
}
stringBuilder.append("{");
stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value);
stringBuilder.append("}");
}
return stringBuilder.toString();
}
}
@@ -29,7 +29,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrappe
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.client.multiplayer.ClientChunkCache;
import net.minecraft.client.multiplayer.ClientLevel;
@@ -95,8 +94,8 @@ public class ChunkWrapper implements IChunkWrapper
//=============//
// constructor //
//=============//
private String stackTraceElements = Arrays.toString(Thread.currentThread().getStackTrace());
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource, @Nullable ILevelWrapper wrappedLevel)
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource, ILevelWrapper wrappedLevel)
{
this.chunk = chunk;
this.lightSource = lightSource;
@@ -157,20 +156,23 @@ public class ChunkWrapper implements IChunkWrapper
@Override
public IBiomeWrapper getBiome(int relX, int relY, int relZ)
{
//if (wrappedLevel != null) return wrappedLevel.getBiome(new DhBlockPos(x + getMinX(), y, z + getMinZ()));
#if PRE_MC_1_17_1
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
relX >> 2, relY >> 2, relZ >> 2));
relX >> 2, relY >> 2, relZ >> 2),
this.wrappedLevel);
#elif PRE_MC_1_18_2
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
this.wrappedLevel);
#elif PRE_MC_1_18_2
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
#else //Now returns a Holder<Biome> instead of Biome
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
this.wrappedLevel);
#else
//Now returns a Holder<Biome> instead of Biome
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)), wrappedLevel);
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
this.wrappedLevel);
#endif
}
@@ -214,7 +216,7 @@ public class ChunkWrapper implements IChunkWrapper
if (this.chunk instanceof LevelChunk)
{
LevelChunk levelChunk = (LevelChunk) this.chunk;
if (this.wrappedLevel instanceof IClientLevelWrapper)
if (levelChunk.getLevel().isClientSide())
{
weakMapLock.readLock().lock();
boolean fixedIsClientLightReady = chunksToUpdateClientLightReady.get(this.chunk);
@@ -368,12 +370,11 @@ public class ChunkWrapper implements IChunkWrapper
@Override
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ)
{
//if (wrappedLevel != null) return wrappedLevel.getBlockState(new DhBlockPos(x + getMinX(), y, z + getMinZ()));
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(new BlockPos(relX, relY, relZ)), wrappedLevel);
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(new BlockPos(relX, relY, relZ)), this.wrappedLevel);
}
@Override
public boolean isStillValid() { return this.wrappedLevel == null || this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
#if POST_MC_1_20_1
private static boolean checkLightSectionsOnChunk(LevelChunk chunk, LevelLightEngine engine)
@@ -385,9 +385,15 @@ public class ClassicConfigGUI
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
// If the update is pending, display this message to inform the user that it will apply when the game restarts
if (SelfUpdater.deleteOldOnClose)
DhDrawString(matrices, font, Translatable(configBase.modID + ".updater.waitingForClose"), 4, height - 38, 0xFFFFFF);
if (this.configBase.modID == "distanthorizons")
{
// Display version
DhDrawString(matrices, font, TextOrLiteral(ModInfo.VERSION), 2, height - 10, 0xAAAAAA);
// If the update is pending, display this message to inform the user that it will apply when the game restarts
if (SelfUpdater.deleteOldOnClose)
DhDrawString(matrices, font, Translatable(configBase.modID + ".updater.waitingForClose"), 4, height - 38, 0xFFFFFF);
}
// Render the tooltip only if it can find a tooltip in the language file
@@ -165,7 +165,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Override
public IBlockStateWrapper getBlockState(DhBlockPos pos)
{
return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), getWrapper(level));
return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), this);
}
@Override
@@ -140,7 +140,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
public IChunkWrapper tryGetChunk(DhChunkPos pos)
{
if (!level.hasChunk(pos.x, pos.z)) return null;
ChunkAccess chunk = level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
ChunkAccess chunk = level.getChunk(pos.x, pos.z, ChunkStatus.EMPTY, false);
if (chunk == null) return null;
return new ChunkWrapper(chunk, level, this);
}
@@ -156,7 +156,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
@Override
public IBlockStateWrapper getBlockState(DhBlockPos pos)
{
return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos)), getWrapper(level));
return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos)), this);
}
@Override
@@ -484,7 +484,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
ChunkAccess chunk = totalChunks.get(x, z);
if (chunk != null)
{
chunkWrapperList.set(x, z, new ChunkWrapper(chunk, region, this.serverlevel.getServerLevelWrapper()));
chunkWrapperList.set(x, z, new ChunkWrapper(chunk, region, serverlevel.getLevelWrapper()));
}
});
+3 -1
View File
@@ -12,7 +12,9 @@ loom {
setConfigName("Fabric Client")
ideConfigGenerated(false)
runDir("run/client")
<<<<<<< Updated upstream
=======
>>>>>>> Stashed changes
}
server {
server()
@@ -31,6 +31,18 @@ public class MixinChunkMap
@Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE))
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
{
// corrupt/incomplete chunk validation
#if MC_1_18_2
// MC 1.18.2 has the tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
// this should prevent that from happening
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
{
return;
}
#endif
// biome validation
#if MC_1_16_5 || MC_1_17_1
if (chunk.getBiomes() == null)
{
@@ -1,8 +1,8 @@
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
#if MC_1_16_5
#elif PRE_MC_1_19_2
#if MC_1_16_5 || MC_1_17_1
#elif MC_1_18_2
import ru.bclib.config.ClientConfig;
import ru.bclib.config.Configs;
#else
@@ -17,8 +17,8 @@ public class BCLibAccessor implements IBCLibAccessor
public void setRenderCustomFog(boolean newValue)
{
#if MC_1_16_5 || MC_1_17_1
#elif PRE_MC_1_19_2
#if !(MC_1_16_5 || MC_1_17_1) // 1.16 and 1.17 don't have "ClientConfig.CUSTOM_FOG_RENDERING"
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
// This disabled fog from rendering within bclib
Configs.CLIENT_CONFIG.set(ClientConfig.CUSTOM_FOG_RENDERING, newValue);
@@ -1,30 +1,29 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.fabric.mixins",
"mixins": [
"server.unsafe.MixinThreadingDetector",
"server.MixinChunkGenerator",
"server.MixinChunkMap",
"server.MixinUtilBackgroundThread"
],
"client": [
"client.MixinClientLevel",
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinGameRenderer",
"client.MixinLevelRenderer",
"client.MixinLightmap",
"client.MixinOptionsScreen",
"client.MixinMinecraft",
"client.MixinTextureUtil",
"mods.sodium.MixinSodiumRenderer"
],
"server": [],
"injectors": {
"defaultRequire": 1
},
"plugin": "com.seibel.distanthorizons.fabric.mixins.FabricMixinPlugin"
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.fabric.mixins",
"mixins": [
"server.unsafe.MixinThreadingDetector",
"server.MixinChunkGenerator",
"server.MixinChunkMap",
"server.MixinUtilBackgroundThread"
],
"client": [
"client.MixinClientLevel",
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinGameRenderer",
"client.MixinLevelRenderer",
"client.MixinLightmap",
"client.MixinOptionsScreen",
"client.MixinMinecraft",
"client.MixinTextureUtil",
"mods.sodium.MixinSodiumRenderer"
],
"server": [],
"injectors": {
"defaultRequire": 1
},
"plugin": "com.seibel.distanthorizons.fabric.mixins.FabricMixinPlugin"
}
+55 -52
View File
@@ -1,56 +1,59 @@
{
"schemaVersion": 1,
"id": "distanthorizons",
"version": "${version}",
"name": "${mod_name}",
"description": "${description}",
"authors": $authors,
"contact": {
"homepage": "${homepage}",
"sources": "${source}",
"issues": "${issues}"
},
"license": "LGPL-3",
"icon": "icon.png",
"accessWidener": "distanthorizons.accesswidener",
"environment": "*",
"entrypoints": {
"client": [
"com.seibel.distanthorizons.fabric.FabricClientMain"
"schemaVersion": 1,
"id": "distanthorizons",
"version": "${version}",
"name": "${mod_name}",
"description": "${description}",
"authors": $authors,
"contact": {
"homepage": "${homepage}",
"sources": "${source}",
"issues": "${issues}"
},
"license": "LGPL-3",
"icon": "icon.png",
"accessWidener": "distanthorizons.accesswidener",
"environment": "*",
"entrypoints": {
"client": [
"com.seibel.distanthorizons.fabric.FabricClientMain"
],
"server": [
"com.seibel.distanthorizons.fabric.FabricDedicatedServerMain"
],
"modmenu": [
"com.seibel.distanthorizons.fabric.wrappers.config.ModMenuIntegration"
]
},
"mixins": [
"DistantHorizons.fabric.mixins.json"
],
"server": [
"com.seibel.distanthorizons.fabric.FabricDedicatedServerMain"
],
"modmenu": [
"com.seibel.distanthorizons.fabric.wrappers.config.ModMenuIntegration"
]
},
"mixins": [
"DistantHorizons.fabric.mixins.json"
],
"depends": {
"fabricloader": "*",
"fabric-api-base": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-key-binding-api-v1": "*",
"fabric-resource-loader-v0": "*",
"minecraft": $compatible_minecraft_versions,
"java": ">=${java_version}"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "${discord}"
}
"depends": {
"fabricloader": "*",
"fabric-api-base": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-key-binding-api-v1": "*",
"fabric-resource-loader-v0": "*",
"minecraft": $compatible_minecraft_versions,
"java": ">=${java_version}"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "${discord}"
}
}
},
"suggests": {
"blendium": "*"
}
}
}
@@ -1,23 +1,23 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.forge.mixins",
"mixins": [
"server.unsafe.MixinThreadingDetector",
"server.MixinUtilBackgroundThread",
"server.MixinChunkGenerator",
"server.MixinTFChunkGenerator"
],
"client": [
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinGameRenderer",
"client.MixinLevelRenderer",
"client.MixinLightmap",
"client.MixinOptionsScreen",
"client.MixinTextureUtil"
],
"server": [],
"plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin"
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.forge.mixins",
"mixins": [
"server.unsafe.MixinThreadingDetector",
"server.MixinUtilBackgroundThread",
"server.MixinChunkGenerator",
"server.MixinTFChunkGenerator"
],
"client": [
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinGameRenderer",
"client.MixinLevelRenderer",
"client.MixinLightmap",
"client.MixinOptionsScreen",
"client.MixinTextureUtil"
],
"server": [],
"plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin"
}
+26 -27
View File
@@ -1,33 +1,32 @@
modLoader="javafml" #//mandatory
loaderVersion="*" # // mandatory. Allow all forge versions as we are definding what Minecraft versions we requre later on
license="LGPL"
issueTrackerURL="${issues}"
modLoader = "javafml" #//mandatory
loaderVersion = "*" # // mandatory. Allow all forge versions as we are definding what Minecraft versions we requre later on
license = "LGPL"
issueTrackerURL = "${issues}"
[[mods]] #//mandatory
modId="distanthorizons" #//mandatory
version= "${version}" #//mandatory, gets the version number from jar populated by the build.gradle script
displayName="${mod_name}" #//mandatory
authors=["James Seibel", "Leonardo Amato", "Cola", "coolGi", "Ran", "Leetom"]
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
displayURL="${homepage}"
description= "${description}" #//mandatory. The description text for the mod
logoFile="logo.png"
catalogueImageIcon="icon.png"
credits="Massive thanks to: Leonardo, Cola, Ran, CoolGi, and Leetom. For their hard work to bring Distant Horizons to where it is today. - James"
#// if not set defaults to "false"
clientSideOnly="true"
#// if not set side defaults to "BOTH"
#// TODO change to "BOTH" when we add server support
side="CLIENT"
#// Allow any version to be present (or not) on the server
acceptableRemoteVersions="*"
modId = "distanthorizons" #//mandatory
version = "${version}" #//mandatory, gets the version number from jar populated by the build.gradle script
displayName = "${mod_name}" #//mandatory
authors = ["James Seibel", "Leonardo Amato", "Cola", "coolGi", "Ran", "Leetom"]
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
displayURL = "${homepage}"
description = "${description}" #//mandatory. The description text for the mod
logoFile = "logo.png"
catalogueImageIcon = "icon.png"
credits = "Massive thanks to: Leonardo, Cola, Ran, CoolGi, and Leetom. For their hard work to bring Distant Horizons to where it is today. - James"
#// if not set defaults to "false"
clientSideOnly = "true"
#// if not set side defaults to "BOTH"
#// TODO change to "BOTH" when we add server support
side = "CLIENT"
#// Allow any version to be present (or not) on the server
acceptableRemoteVersions = "*"
[[dependencies.distanthorizons]]
modId="minecraft"
mandatory=true
versionRange="${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
ordering="NONE"
side="BOTH"
modId = "minecraft"
mandatory = true
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
ordering = "NONE"
side = "BOTH"
+8
View File
@@ -30,6 +30,14 @@ netty_version=4.1.94.Final
lwjgl_version=3.2.3
joml_version=1.10.2
# These are here so they can be changed with cmd arguments
# If they are null, they would be automatically set
# (This is mainly used for the CI)
gitMainCommit=null
gitCoreCommit=null
gitMainBranch=null
# Internal Properties (These are set at runtime for Forgix to merge jar's)
versionStr=