diff --git a/build.gradle.kts b/build.gradle.kts index 1bfd4a707..3670202fc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ preRelease(true) -versionProjects(":common:api", version("6.0.0")) -versionProjects(":common:implementation", version("6.0.0")) -versionProjects(":platforms", version("6.0.0")) +versionProjects(":common:api", version("6.0.1")) +versionProjects(":common:implementation", version("6.0.1")) +versionProjects(":platforms", version("6.0.1")) allprojects { diff --git a/common/addons/structure-terrascript-loader/build.gradle.kts b/common/addons/structure-terrascript-loader/build.gradle.kts index 15b7f1107..62422cc79 100644 --- a/common/addons/structure-terrascript-loader/build.gradle.kts +++ b/common/addons/structure-terrascript-loader/build.gradle.kts @@ -1,6 +1,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -version = version("1.0.0") +version = version("1.0.1") dependencies { api("commons-io:commons-io:2.7") diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/generic/pair/Pair.java b/common/api/src/main/java/com/dfsek/terra/api/util/generic/pair/Pair.java index 58d1e7353..ad4c2c879 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/generic/pair/Pair.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/generic/pair/Pair.java @@ -11,6 +11,10 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; public final class Pair { @@ -18,6 +22,38 @@ public final class Pair { private final L left; private final R right; + public static Function, Pair> mapLeft(Function function) { + return pair -> of(function.apply(pair.left), pair.right); + } + + public static Function, Pair> mapRight(Function function) { + return pair -> of(pair.left, function.apply(pair.right)); + } + + public static Predicate> testLeft(Predicate predicate) { + return pair -> predicate.test(pair.left); + } + + public static Predicate> testRight(Predicate predicate) { + return pair -> predicate.test(pair.right); + } + + public static Consumer> consumeLeft(Consumer consumer) { + return pair -> consumer.accept(pair.left); + } + + public static Consumer> consumeRight(Consumer consumer) { + return pair -> consumer.accept(pair.right); + } + + public static Function, R> unwrapRight() { + return pair -> pair.right; + } + + public static Function, L> unwrapLeft() { + return pair -> pair.left; + } + private Pair(L left, R right) { this.left = left; this.right = right; @@ -108,4 +144,9 @@ public final class Pair { return Objects.equals(this.left, that.left) && Objects.equals(this.right, that.right); } } + + @Override + public String toString() { + return String.format("{%s,%s}", left, right); + } } diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java b/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java index 9509f38b9..21ff745fe 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/AbstractPlatform.java @@ -18,6 +18,9 @@ package com.dfsek.terra; import com.dfsek.tectonic.api.TypeRegistry; + +import com.dfsek.terra.api.util.generic.pair.Pair; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.NotNull; @@ -33,12 +36,15 @@ import java.io.OutputStream; import java.io.UncheckedIOException; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import com.dfsek.terra.addon.BootstrapAddonLoader; import com.dfsek.terra.addon.DependencySorter; @@ -212,13 +218,71 @@ public abstract class AbstractPlatform implements Platform { logger.info("No resources config found. Skipping resource dumping."); return; } + + Path data = getDataFolder().toPath(); + + Path addonsPath = data.resolve("addons"); + Set> paths = Files + .walk(addonsPath) + .map(path -> Pair.of(path, data.relativize(path).toString())) + + .map(Pair.mapRight(s -> { + if(s.contains("+")) { // remove commit hash + return s.substring(0, s.lastIndexOf('+')); + } + return s; + })) + + .filter(Pair.testRight(s -> s.contains("."))) // remove patch version + .map(Pair.mapRight(s -> s.substring(0, s.lastIndexOf('.')))) + + .filter(Pair.testRight(s -> s.contains("."))) // remove minor version + .map(Pair.mapRight(s -> s.substring(0, s.lastIndexOf('.')))) + + .collect(Collectors.toSet()); + + Set pathsNoMajor = paths + .stream() + .filter(Pair.testRight(s -> s.contains("."))) + .map(Pair.mapRight(s -> s.substring(0, s.lastIndexOf('.')))) // remove major version + .map(Pair.unwrapRight()) + .collect(Collectors.toSet()); + + + // Terra-aaa-aaa-1.2.3-BETA+1e6af8923d.jar String resourceYaml = IOUtils.toString(resourcesConfig, StandardCharsets.UTF_8); Map> resources = new Yaml().load(resourceYaml); resources.forEach((dir, entries) -> entries.forEach(entry -> { - String resourcePath = String.format("%s/%s", dir, entry); + String resourcePath = dir + File.separatorChar + entry; File resource = new File(getDataFolder(), resourcePath); if(resource.exists()) return; // dont overwrite + + paths + .stream() + .filter(Pair.testRight(resourcePath::startsWith)) + .forEach(Pair.consumeLeft(path -> { + logger.info("Removing outdated resource {}, replacing with {}", path, resourcePath); + try { + Files.delete(path); + } catch(IOException e) { + throw new UncheckedIOException(e); + } + })); + + if(pathsNoMajor + .stream() + .anyMatch(resourcePath::startsWith) && // if any share name + paths + .stream() + .map(Pair.unwrapRight()) + .noneMatch(resourcePath::startsWith)) { // but dont share major version + logger.warn( + "Addon {} has a new major version available. It will not be automatically updated; you will need to ensure " + + "compatibility and update manually.", + resourcePath); + } + logger.info("Dumping resource {}...", resource.getAbsolutePath()); try { resource.getParentFile().mkdirs(); diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java index fc68790e3..b9c4ceb10 100644 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java +++ b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java @@ -54,7 +54,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator { private final long seed; private final Map>> h = new Object2ObjectArrayMap<>(); - + private static final Lazy> EMPTY = Lazy.lazy(List::of); public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { @@ -154,7 +154,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator { @Override public List a(ConcentricRingsStructurePlacement concentricringsstructureplacement) { this.i(); - return this.h.get(concentricringsstructureplacement).value(); + return this.h.getOrDefault(concentricringsstructureplacement, EMPTY).value(); } private volatile boolean rings = false;