Update core
This commit is contained in:
+3
-3
@@ -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:
|
||||
|
||||
@@ -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
@@ -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"
|
||||
}
|
||||
|
||||
+31
-7
@@ -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!
|
||||
|
||||
+168
-91
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+265
-233
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+15
-14
@@ -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)
|
||||
|
||||
+9
-3
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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()));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+1
-1
Submodule coreSubProjects updated: c5abc22c58...517925a207
+3
-1
@@ -12,7 +12,9 @@ loom {
|
||||
setConfigName("Fabric Client")
|
||||
ideConfigGenerated(false)
|
||||
runDir("run/client")
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
>>>>>>> Stashed changes
|
||||
}
|
||||
server {
|
||||
server()
|
||||
|
||||
+12
@@ -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)
|
||||
{
|
||||
|
||||
+4
-4
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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=
|
||||
|
||||
|
||||
Reference in New Issue
Block a user