mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 14:50:56 +00:00
Merge pull request #119 from PolyhedralDev/ver/5.1.3
Fix Fabric Physics, add "dead" entry checking to registries.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import com.dfsek.terra.getGitHash
|
import com.dfsek.terra.getGitHash
|
||||||
|
|
||||||
val versionObj = Version("5", "1", "2", true)
|
val versionObj = Version("5", "1", "3", true)
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = versionObj
|
version = versionObj
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ fun Project.configureDependencies() {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||||
"testImplementation"("org.yaml:snakeyaml:1.27")
|
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||||
"testImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
|
||||||
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
|
||||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,8 +62,14 @@ fun Project.configureDistribution() {
|
|||||||
archiveClassifier.set("shaded")
|
archiveClassifier.set("shaded")
|
||||||
setVersion(project.version)
|
setVersion(project.version)
|
||||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||||
relocate("parsii", "com.dfsek.terra.lib.parsii")
|
|
||||||
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
|
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
|
||||||
|
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||||
|
relocate("com.google.errorprone", "com.dfsek.terra.lib.google.errorprone")
|
||||||
|
relocate("com.google.j2objc", "com.dfsek.terra.lib.google.j2objc")
|
||||||
|
relocate("org.checkerframework", "com.dfsek.terra.lib.checkerframework")
|
||||||
|
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
|
||||||
|
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||||
|
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||||
minimize()
|
minimize()
|
||||||
}
|
}
|
||||||
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ dependencies {
|
|||||||
"shadedApi"("org.ow2.asm:asm:9.0")
|
"shadedApi"("org.ow2.asm:asm:9.0")
|
||||||
"shadedApi"("commons-io:commons-io:2.6")
|
"shadedApi"("commons-io:commons-io:2.6")
|
||||||
|
|
||||||
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
|
"shadedApi"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||||
|
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||||
|
|
||||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
||||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||||
|
checkDeadEntries(main);
|
||||||
} catch(FileNotFoundException e) {
|
} catch(FileNotFoundException e) {
|
||||||
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||||
}
|
}
|
||||||
@@ -183,6 +184,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
selfLoader.load(packPostTemplate, file.getInputStream(pack));
|
selfLoader.load(packPostTemplate, file.getInputStream(pack));
|
||||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||||
|
checkDeadEntries(main);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||||
}
|
}
|
||||||
@@ -198,6 +200,16 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkDeadEntries(TerraPlugin main) {
|
||||||
|
biomeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in biome registry: '" + id + "'"));
|
||||||
|
paletteRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in palette registry: '" + id + "'"));
|
||||||
|
floraRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in flora registry: '" + id + "'"));
|
||||||
|
carverRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in carver registry: '" + id + "'"));
|
||||||
|
treeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in tree registry: '" + id + "'"));
|
||||||
|
oreRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in ore registry: '" + id + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
|
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,19 @@ import com.dfsek.terra.registry.exception.DuplicateEntryException;
|
|||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry implementation with read/write access. For internal use only.
|
* Registry implementation with read/write access. For internal use only.
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public class OpenRegistry<T> implements Registry<T> {
|
public class OpenRegistry<T> implements Registry<T> {
|
||||||
private final Map<String, T> objects = new HashMap<>();
|
private final Map<String, Entry<T>> objects = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||||
@@ -35,6 +36,10 @@ public class OpenRegistry<T> implements Registry<T> {
|
|||||||
* @param value Value to add.
|
* @param value Value to add.
|
||||||
*/
|
*/
|
||||||
public boolean add(String identifier, T value) {
|
public boolean add(String identifier, T value) {
|
||||||
|
return add(identifier, new Entry<>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean add(String identifier, Entry<T> value) {
|
||||||
boolean exists = objects.containsKey(identifier);
|
boolean exists = objects.containsKey(identifier);
|
||||||
objects.put(identifier, value);
|
objects.put(identifier, value);
|
||||||
return exists;
|
return exists;
|
||||||
@@ -60,22 +65,22 @@ public class OpenRegistry<T> implements Registry<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get(String identifier) {
|
public T get(String identifier) {
|
||||||
return objects.get(identifier);
|
return objects.get(identifier).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEach(Consumer<T> consumer) {
|
public void forEach(Consumer<T> consumer) {
|
||||||
objects.forEach((id, obj) -> consumer.accept(obj));
|
objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEach(BiConsumer<String, T> consumer) {
|
public void forEach(BiConsumer<String, T> consumer) {
|
||||||
objects.forEach(consumer);
|
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<T> entries() {
|
public Set<T> entries() {
|
||||||
return new HashSet<>(objects.values());
|
return objects.values().stream().map(Entry::getRaw).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,10 +88,41 @@ public class OpenRegistry<T> implements Registry<T> {
|
|||||||
return objects.keySet();
|
return objects.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, T> getDeadEntries() {
|
||||||
|
Map<String, T> dead = new HashMap<>();
|
||||||
|
objects.forEach((id, entry) -> {
|
||||||
|
if(entry.dead()) dead.put(id, entry.value); // dont increment value here.
|
||||||
|
});
|
||||||
|
return dead;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all entries from the registry.
|
* Clears all entries from the registry.
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
objects.clear();
|
objects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static final class Entry<T> {
|
||||||
|
private final T value;
|
||||||
|
private final AtomicInteger access = new AtomicInteger(0);
|
||||||
|
|
||||||
|
public Entry(T value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getValue() {
|
||||||
|
access.incrementAndGet();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private T getRaw() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dead() {
|
||||||
|
return access.get() == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ public class FloraRegistry extends OpenRegistry<Flora> {
|
|||||||
|
|
||||||
private void addItem(String id, Callable<ConstantFlora> flora) {
|
private void addItem(String id, Callable<ConstantFlora> flora) {
|
||||||
try {
|
try {
|
||||||
add(id, flora.call());
|
Entry<Flora> entry = new Entry<>(flora.call());
|
||||||
|
entry.getValue(); // Mark as not dead.
|
||||||
|
add(id, entry);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage());
|
main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,12 @@ configureCommon()
|
|||||||
group = "com.dfsek.terra.bukkit"
|
group = "com.dfsek.terra.bukkit"
|
||||||
|
|
||||||
val mcVersion = "1.16.5"
|
val mcVersion = "1.16.5"
|
||||||
val testDir = "target/server/"
|
val testDir = "target/server"
|
||||||
val testMem = "3G"
|
val testMem = "3G"
|
||||||
|
|
||||||
val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/"
|
val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/"
|
||||||
val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar"
|
val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar"
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
maven { url = uri("http://maven.enginehub.org/repo/") }
|
|
||||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
|
||||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"shadedApi"(project(":common"))
|
"shadedApi"(project(":common"))
|
||||||
|
|
||||||
@@ -39,17 +32,17 @@ dependencies {
|
|||||||
|
|
||||||
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
|
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
|
||||||
|
|
||||||
"shadedImplementation"("com.google.guava:guava:30.0-jre")
|
"shadedApi"("com.google.guava:guava:30.0-jre")
|
||||||
}
|
}
|
||||||
|
|
||||||
val aikarsFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
val jvmFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
||||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
|
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
|
||||||
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
|
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
|
||||||
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
|
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
|
||||||
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
|
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
|
||||||
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
|
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
|
||||||
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
|
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
|
||||||
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear")
|
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear", "-javaagent:paperclip.jar")
|
||||||
|
|
||||||
fun downloadPaperclip(url: String, dir: String) {
|
fun downloadPaperclip(url: String, dir: String) {
|
||||||
val clip = URL(url.replace("%version%", mcVersion))
|
val clip = URL(url.replace("%version%", mcVersion))
|
||||||
@@ -160,7 +153,7 @@ task<JavaExec>(name = "runPaper") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main = "io.papermc.paperclip.Paperclip"
|
main = "io.papermc.paperclip.Paperclip"
|
||||||
jvmArgs = aikarsFlags
|
jvmArgs = jvmFlags
|
||||||
maxHeapSize = testMem
|
maxHeapSize = testMem
|
||||||
minHeapSize = testMem
|
minHeapSize = testMem
|
||||||
//args = listOf("nogui")
|
//args = listOf("nogui")
|
||||||
@@ -178,7 +171,7 @@ task<JavaExec>(name = "runPurpur") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main = "io.papermc.paperclip.Paperclip"
|
main = "io.papermc.paperclip.Paperclip"
|
||||||
jvmArgs = aikarsFlags
|
jvmArgs = jvmFlags
|
||||||
maxHeapSize = testMem
|
maxHeapSize = testMem
|
||||||
minHeapSize = testMem
|
minHeapSize = testMem
|
||||||
//args = listOf("nogui")
|
//args = listOf("nogui")
|
||||||
@@ -189,6 +182,7 @@ task<JavaExec>(name = "runPurpur") {
|
|||||||
tasks.named<ShadowJar>("shadowJar") {
|
tasks.named<ShadowJar>("shadowJar") {
|
||||||
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
|
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
|
||||||
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
|
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
|
||||||
|
relocate("com.google.common", "com.dfsek.terra.lib.google.common")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ public class TerraListener implements EventListener {
|
|||||||
public void injectTrees(ConfigPackPreLoadEvent event) {
|
public void injectTrees(ConfigPackPreLoadEvent event) {
|
||||||
for(TreeType value : TreeType.values()) {
|
for(TreeType value : TreeType.values()) {
|
||||||
try {
|
try {
|
||||||
event.getPack().getTreeRegistry().add(BukkitAdapter.TREE_TRANSFORMER.translate(value), new BukkitTree(value, main));
|
String id = BukkitAdapter.TREE_TRANSFORMER.translate(value);
|
||||||
|
event.getPack().getTreeRegistry().add(id, new BukkitTree(value, main));
|
||||||
|
event.getPack().getTreeRegistry().get(id); // Platform trees should never be marked "dead"
|
||||||
} catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing.
|
} catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ group = "com.dfsek.terra.fabric"
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"shadedApi"(project(":common"))
|
"shadedApi"(project(":common"))
|
||||||
"shadedImplementation"("org.yaml:snakeyaml:1.27")
|
|
||||||
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
|
||||||
|
|
||||||
"minecraft"("com.mojang:minecraft:1.16.5")
|
"minecraft"("com.mojang:minecraft:1.16.5")
|
||||||
"mappings"("net.fabricmc:yarn:1.16.5+build.5:v2")
|
"mappings"("net.fabricmc:yarn:1.16.5+build.5:v2")
|
||||||
@@ -32,11 +30,6 @@ dependencies {
|
|||||||
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
|
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<ShadowJar>("shadowJar") {
|
|
||||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
|
||||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
configure<LoomGradleExtension> {
|
configure<LoomGradleExtension> {
|
||||||
accessWidener("src/main/resources/terra.accesswidener")
|
accessWidener("src/main/resources/terra.accesswidener")
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.block.state.BlockState;
|
|||||||
import com.dfsek.terra.fabric.world.FabricAdapter;
|
import com.dfsek.terra.fabric.world.FabricAdapter;
|
||||||
import com.dfsek.terra.fabric.world.block.state.FabricBlockState;
|
import com.dfsek.terra.fabric.world.block.state.FabricBlockState;
|
||||||
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
|
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
|
||||||
|
import net.minecraft.block.FluidBlock;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.WorldAccess;
|
import net.minecraft.world.WorldAccess;
|
||||||
|
|
||||||
@@ -21,7 +22,10 @@ public class FabricBlock implements Block {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlockData(BlockData data, boolean physics) {
|
public void setBlockData(BlockData data, boolean physics) {
|
||||||
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042, 0);
|
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042);
|
||||||
|
if(physics && ((FabricBlockData) data).getHandle().getBlock() instanceof FluidBlock) {
|
||||||
|
delegate.worldAccess.getFluidTickScheduler().schedule(delegate.position, ((FluidBlock) ((FabricBlockData) data).getHandle().getBlock()).getFluidState(((FabricBlockData) data).getHandle()).getFluid(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user